📄 3dengine.cpp
字号:
// (C) Copyright 1996 by Anthony J. Carin. All Rights Reserved.
#include <stdafx.h>
#include "3dengine.h"
#include <stdlib.h>
#include "scrlsurf.h"
#include "3dtools.h"
#include "command.h"
view camera;
const short BUFSIZE = 500;
const uchar COLORDIFF = 10;
image::image(LPCTSTR filename, direction ydir)
{
readfile(filename);
m_size = 1.0f;
color = RGB(255,255,255);
m_yoff = ydir;
}
image::~image()
{
for (int i = 0; i < numsurfs; i++)
{
delete m_surfs[i];
delete m_mysurfs[i];
}
delete [] m_points;
delete [] m_surfs;
delete [] m_mysurfs;
}
void image::setbmpsurf(short index, CString& face)
{
if (index < 0 ||
index >= numsurfs ||
Game->Detail() < 7)
return;
delete m_mysurfs[index];
m_mysurfs[index] = new bmpsurf(face);
((bmpsurf *)m_mysurfs[index])->ExemptFromIntersect();
}
void image::readfile(LPCTSTR filename)
{
char buf[BUFSIZE];
fptr = fopen(filename, "r");
if (fptr > 0)
{
getsize(buf);
getpoints(buf);
getsurfaces(buf);
buf[0] = 0;
fgets(buf, BUFSIZE, fptr);
if (buf[0] != 0)
findend(buf);
m_genstring = buf;
fclose(fptr);
}
}
void image::getsize(char *buf)
{
char *ptr;
fgets(buf, BUFSIZE, fptr);
ptr = findend(buf);
findend(ptr);
numpoints = (short)atoi(buf);
numsurfs = (short)atoi(ptr);
m_points = new point[numpoints];
m_surfs = (surfs **) new char[numsurfs*sizeof(surfs *)];
m_mysurfs = (surfs **) new char[numsurfs*sizeof(surfs *)];
for (short i = 0; i < numsurfs; i++)
{
m_surfs[i] = new surfs();
m_mysurfs[i] = new surfs();
}
}
void image::getpoints(char *buf)
{
char *ptr1, *ptr2;
for (short i = 0; i < numpoints; i++)
{
fgets(buf, BUFSIZE, fptr);
ptr1 = findend(buf);
ptr2 = findend(ptr1);
findend(ptr2);
m_points[i].setto(convertfloat(buf), -convertfloat(ptr1), convertfloat(ptr2));
}
}
void image::getsurfaces(char *buf)
{
char type;
char *ptr1, *ptr2, *ptr3, *ptr4, *ptr5;
short p1,p2,p3,p4 = 0;
CString p5;
for (short i = 0; i < numsurfs; i++)
{
fgets(buf, BUFSIZE, fptr);
type = (char)atoi(buf);
ptr1 = findend(buf);
p1 = (short)(atoi(ptr1) - 1);
ptr2 = findend(ptr1);
p2 = (short)(atoi(ptr2) - 1);
ptr3 = findend(ptr2);
p3 = (short)(atoi(ptr3) - 1);
ptr4 = findend(ptr3);
if (type >= 4 && type <= 6)
{
p4 = (short)(atoi(ptr4) - 1);
ptr5 = findend(ptr4);
if (type == 5 || type == 6)
{
int numbmps = multiplesurfs(ptr5);
if (numbmps > 1)
{
delete m_mysurfs[i];
scrollsurf *sptr = new scrollsurf();
while (numbmps--)
{
ptr4 = findend(ptr5);
p5 = (CString) ptr5;
sptr->addsurf(p5);
ptr5 = ptr4;
}
m_mysurfs[i] = sptr;
if (type == 6)
((bmpsurf *) m_mysurfs[i])->ExemptFromIntersect();
}
else
{
findend(ptr5);
p5 = (CString) ptr5;
delete m_mysurfs[i];
m_mysurfs[i] = new bmpsurf(p5);
if (type == 6)
((bmpsurf *) m_mysurfs[i])->ExemptFromIntersect();
}
}
}
if (type == 3)
m_surfs[i]->setto(m_points[p1], m_points[p2], m_points[p3]);
else
m_surfs[i]->setto(m_points[p1], m_points[p2], m_points[p3], m_points[p4]);
m_surfs[i]->CalcNormals();
}
}
char * image::findend(char *ptr)
{
while (*ptr != ' ' && *ptr != '\n')
ptr++;
*ptr++ = 0;
return ptr;
}
int image::multiplesurfs(char *ptr)
{
int num = 1;
char spaces = FALSE;
while (*ptr != '\0' && *ptr != '\n')
{
if (*ptr == ' ' || *ptr == '\t')
spaces = TRUE;
if (*ptr != ' ' && *ptr != '\t' && spaces == TRUE)
{
spaces = FALSE;
num++;
}
ptr++;
}
return num;
}
void image::draw()
{
if (outofrange())
return;
copysurfs();
Game->Tool3d()->material(color);
if (Game->Detail() < 10)
{
for (short i = 0; i < numsurfs; i++)
if (m_mysurfs[i]->IsABmp() || random((short)((int)Game->Detail()+2)) != 1)
m_mysurfs[i]->draw();
}
else
{
for (short i = 0; i < numsurfs; i++)
m_mysurfs[i]->draw();
}
}
char image::outofrange()
{
xdirfromcamera = camera.xdirectionto(m_view);
ydirfromcamera = camera.ydirectionto(m_view);
direction xdir = xdirfromcamera - camera.xdirection();
direction ydir = ydirfromcamera - camera.ydirection();
if (camera.distanceto(m_view) > VIEWRANGE)
return TRUE;
if (ydir > (direction) TC_PI && ydir < (direction) -TC_PI)
return TRUE;
if (xdir > (direction) TC_PI && xdir < (direction) -TC_PI)
return TRUE;
return FALSE;
}
void image::OnlySurfExemptFromIntersect()
{
if (numsurfs > 0)
{
if (m_mysurfs[0]->IsABmp())
((bmpsurf *)m_mysurfs[0])->ExemptFromIntersect();
}
}
surfs * image::OnlySurf()
{
if (numsurfs > 0)
return m_mysurfs[0];
return (surfs *) 0;
}
void image::copysurfs()
{
for (short i = 0; i < numsurfs; i++)
{
*m_mysurfs[i] = *m_surfs[i];
m_mysurfs[i]->xrotate(m_view.xdirection());
m_mysurfs[i]->zrotate(m_view.zdirection());
m_mysurfs[i]->yrotate(m_view.ydirection()+m_yoff);
*m_mysurfs[i] += m_view;
}
}
void surfs::operator =(surfs& s)
{
NormalX = s.NormalX;
NormalY = s.NormalY;
NormalZ = s.NormalZ;
polygon::operator =(s);
}
void surfs::xrotate(direction& d)
{
if (!d.iszero())
{
m_a.xrotate(d);
m_b.xrotate(d);
m_c.xrotate(d);
m_d.xrotate(d);
}
}
void surfs::yrotate(direction& d)
{
if (!d.iszero())
{
m_a.yrotate(d);
m_b.yrotate(d);
m_c.yrotate(d);
m_d.yrotate(d);
}
}
void surfs::zrotate(direction& d)
{
if (!d.iszero())
{
m_a.zrotate(d);
m_b.zrotate(d);
m_c.zrotate(d);
m_d.zrotate(d);
}
}
void surfs::operator +=(coordinate& c)
{
m_a += c;
m_b += c;
m_c += c;
m_d += c;
}
void surfs::draw()
{
if (m_linenum == 3)
{
Game->Tool3d()->begintriangle();
Game->Tool3d()->normals(NormalX, NormalY, NormalZ);
Game->Tool3d()->vertex(m_a.x(), m_a.y(), m_a.z());
Game->Tool3d()->vertex(m_b.x(), m_b.y(), m_b.z());
Game->Tool3d()->vertex(m_c.x(), m_c.y(), m_c.z());
Game->Tool3d()->end();
}
else
{
Game->Tool3d()->beginquad();
Game->Tool3d()->normals(NormalX, NormalY, NormalZ);
Game->Tool3d()->vertex(m_a.x(), m_a.y(), m_a.z());
Game->Tool3d()->vertex(m_b.x(), m_b.y(), m_b.z());
Game->Tool3d()->vertex(m_c.x(), m_c.y(), m_c.z());
Game->Tool3d()->vertex(m_d.x(), m_d.y(), m_d.z());
Game->Tool3d()->end();
}
}
void surfs::CalcNormals()
{
coordinate a,b;
a = m_b - m_a;
b = m_c - m_a;
NormalX = a.y() * b.z() - a.z() * b.y();
NormalY = a.z() * b.x() - a.x() * b.z();
NormalZ = a.x() * b.y() - a.y() * b.x();
float length = (float)sqrt(NormalX*NormalX+NormalY*NormalY+NormalZ*NormalZ);
if (length != 0)
{
NormalX /= length;
NormalY /= length;
NormalZ /= length;
}
}
char surfs::iswithin(coordinate& c)
{
if (m_linenum == 0)
return FALSE;
if (m_c.x() == m_b.x())
{
if (m_c.z() < m_b.z())
{
if (c.z() < m_c.z() || c.z() > m_b.z())
return FALSE;
}
else
{
if (c.z() < m_b.z() || c.z() > m_c.z())
return FALSE;
}
if (m_c.x() < m_d.x())
{
if (c.x() < m_c.x() || c.x() > m_d.x())
return FALSE;
}
else
{
if (c.x() < m_d.x() || c.x() > m_c.x())
return FALSE;
}
}
else
{
if (m_c.z() < m_d.z())
{
if (c.z() < m_c.z() || c.z() > m_d.z())
return FALSE;
}
else
{
if (c.z() < m_d.z() || c.z() > m_c.z())
return FALSE;
}
if (m_c.x() < m_b.x())
{
if (c.x() < m_c.x() || c.x() > m_b.x())
return FALSE;
}
else
{
if (c.x() < m_b.x() || c.x() > m_c.x())
return FALSE;
}
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -