📄 flyengine.cpp
字号:
#include "../Fly3D.h"
FLY_API flyEngine *flyengine=0;
FLY_API HWND hFlyWnd=0;
FLY_API HINSTANCE hFlyInst=0;
FLY_API void init_engine(HWND hWnd,HINSTANCE hInst,int appid)
{
free_engine();
set_engine(new flyEngine,hWnd,hInst,appid);
}
FLY_API void set_engine(flyEngine *eng,HWND hWnd,HINSTANCE hInst,int appid)
{
flyengine=eng;
flyengine->appid=appid;
hFlyWnd=hWnd;
hFlyInst=hInst;
}
FLY_API void free_engine()
{
if (flyengine)
delete flyengine;
flyengine=0;
}
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
flyEngine::flyEngine()
{
cur_step=cur_step_base=0;
cur_frame=cur_frame_base=0;
start_time=cur_time=cur_dt=0;
intropic=introtime=0;
player=0;
cam=0;
excludecollision=0;
stepobj=0;
nelemdraw=0;
facedraw=0;
nfacedraw=0;
facedrawtransp=0;
nfacedrawtransp=0;
status_msg_time=0;
bboxdiag=viewmaxdist=viewmindist=camangle=aspect=geomdetail=
curveerr=lmpxsize=detailtile=cartoonwidth=shadowdepth=0;
nodedrawcount=nodeonly=pvsoff=fog=mpdelay=antialias=
amblight=mapmode=shadows=noinput=wireframe=mute=mouse=
clearbk=moving=crosshairpic=crosshairsize=appid=multitexture=
detailpic=hwlights=stencil=cartoonpic=cartoonpicbsp=0;
active_obj0=last_active_obj=0;
stock_obj0=0;
model_obj0=0;
sound_obj0=0;
bezier_curve0=0;
bezier_patch0=0;
shadow_obj=0;
hitobj=0;
hitmesh=0;
hitface=0;
status=0;
fontspic=0;
consolepic=0;
vert=vertcolor=vertnormal=0;
nvert=0;
faces=0;
nfaces=0;
edges=0;
nedges=0;
faceedges=0;
bsp=0;
npiclib=0;
nlm=lmbase=nlmpic=0;
fmbase=0;
pvs=0;
leaf=0;
nleaf=pvssize=pvsrowsize=0;
reset();
appid=FLYAPPID_NONE;
start_time=timeGetTime();
strcpy(flysdkpath,GetCommandLine());
if (flysdkpath[0]=='\"')
{
strcpy(flysdkpath,&flysdkpath[1]);
if (strchr(flysdkpath,'\"'))
*strchr(flysdkpath,'\"')=0;
}
if (strrchr(flysdkpath,'\\'))
*(strrchr(flysdkpath,'\\')+1)=0;
else
{
GetCurrentDirectory(255,flysdkpath);
strcat(flysdkpath,"\\");
}
strlwr(flysdkpath);
}
void flyEngine::reset()
{
int i;
bsp_object *d;
mesh *o;
sound *s;
bezier_curve *c;
bezier_patch *p;
while(active_obj0)
{
d=(bsp_object *)active_obj0->next_obj;
delete active_obj0;
active_obj0=d;
}
last_active_obj=0;
while(stock_obj0)
{
d=(bsp_object *)stock_obj0->next_obj;
delete stock_obj0;
stock_obj0=d;
}
while(model_obj0)
{
o=(mesh *)model_obj0->next_obj;
delete model_obj0;
model_obj0=o;
}
while(sound_obj0)
{
s=(sound *)sound_obj0->next_obj;
delete sound_obj0;
sound_obj0=s;
}
while(bezier_curve0)
{
c=(bezier_curve *)bezier_curve0->next_obj;
delete bezier_curve0;
bezier_curve0=c;
}
while(bezier_patch0)
{
p=(bezier_patch *)bezier_patch0->next_obj;
delete bezier_patch0;
bezier_patch0=p;
}
if (bsp)
delete bsp;
bsp=0;
if (vert)
delete vert;
vert=0;
if (vertnormal)
delete vertnormal;
vertnormal=0;
if (vertcolor)
delete vertcolor;
vertcolor=0;
if (faces)
delete faces;
faces=0;
if (edges)
delete edges;
edges=0;
if (faceedges)
delete faceedges;
faceedges=0;
nvert=0;
nfaces=0;
nedges=0;
if (npiclib)
for( i=0;i<npiclib;i++ )
delete piclib[i];
npiclib=0;
if (pvs)
delete pvs;
pvs=0;
pvssize=0;
pvsrowsize=0;
if (leaf)
delete leaf;
leaf=0;
nleaf=0;
if (facedraw)
delete facedraw;
facedraw=0;
if (facedrawtransp)
delete facedrawtransp;
facedrawtransp=0;
for( i=0;i<nlmpic;i++ )
{
delete lmpic[i];
delete fmpic[i];
}
for( i=0;i<nlm;i++ )
{
delete lm[i];
delete fm[i];
}
nlm=0;
nlmpic=0;
lmbase=0;
fmbase=0;
dll.reset();
fontspic=-1;
crosshairpic=-1;
detailpic=-1;
intropic=-1;
consolepic=-1;
cartoonpicbsp=-1;
cartoonpic=-1;
bspfile[0]=0;
flydatapath[0]=0;
flyfile[0]=0;
flyfilename[0]=0;
console_command[0]=0;
status_msg[0]=0;
status_msg_time=0;
nodedrawcount=nfacedraw=nfacedrawtransp=0;
cur_frame=cur_frame_base=0;
cur_step=cur_step_base=0;
cur_time=cur_dt=0;
filter.vec(0,0,0);
background.vec(0,0,0);
clearbk=1;
introtime=2000;
cam=0;
player=0;
}
void flyEngine::compute_normals()
{
// simple and fast vertex normals
int i,j;
if (vertnormal)
delete vertnormal;
vertnormal=new vector[nvert];
memset(vertnormal,0,sizeof(vector)*nvert);
for( j=0;j<nfaces;j++ )
{
vertnormal[faces[j].vert[0]-vert]+=faces[j].normal;
vertnormal[faces[j].vert[1]-vert]+=faces[j].normal;
vertnormal[faces[j].vert[2]-vert]+=faces[j].normal;
}
for( i=0;i<nvert;i++ )
vertnormal[i].normalize();
for( i=0;i<nfaces;i++ )
for( j=0;j<3;j++ )
faces[i].vertnormal[j]=vertnormal[faces[i].vert[j]-vert];
/*
// more accurate and slower vertex normals
if (vertnormal)
delete vertnormal;
vector *nn=new vector[nfaces];
vertnormal=new vector[nvert];
int i,j,k,nc;
for( i=0;i<nvert;i++ )
{
nc=0;
for( j=0;j<nfaces;j++ )
if (faces[j].vert[0]==&vert[i] ||
faces[j].vert[1]==&vert[i] ||
faces[j].vert[2]==&vert[i])
{
for( k=0;k<nc;k++ )
if (vec_dot(faces[j].normal,nn[k])>0.999848f)
break;
if (k==nc)
nn[nc++]=faces[j].normal;
}
vertnormal[i].null();
if (nc)
{
for( k=0;k<nc;k++ )
vertnormal[i]+=nn[k];
vertnormal[i].normalize();
}
}
for( i=0;i<nfaces;i++ )
for( j=0;j<3;j++ )
faces[i].vertnormal[j]=vertnormal[faces[i].vert[j]-vert];
delete nn;
*/
// bound box
bbox1.vec(BIG,BIG,BIG);
bbox2.vec(-BIG,-BIG,-BIG);
for( i=0;i<nvert;i++ )
{
if (vert[i].x>bbox2.x)
bbox2.x=vert[i].x;
if (vert[i].y>bbox2.y)
bbox2.y=vert[i].y;
if (vert[i].z>bbox2.z)
bbox2.z=vert[i].z;
if (vert[i].x<bbox1.x)
bbox1.x=vert[i].x;
if (vert[i].y<bbox1.y)
bbox1.y=vert[i].y;
if (vert[i].z<bbox1.z)
bbox1.z=vert[i].z;
}
bboxdiag=(bbox2-bbox1).length();
bboxC=(bbox1+bbox2)*0.5f;
}
int flyEngine::collision_bsp(bsp_node *n,vector& p1,vector& p2,int elemtype,float rad)
{
if (n->leaf!=-1)
{
bsp_object *e=n->elem;
vector rd=p2-p1;
float dist=1.0f,d;
mesh *m;
vector ip;
int f;
hitobj=0;
while(e)
{
if (e!=flyengine->excludecollision &&
(elemtype==0 || e->type==elemtype))
{
m=e->ray_intersect(p1,rd,ip,d,f,rad);
if (m && d<dist)
{
dist=d;
hitobj=e;
hitip=ip;
hitface=f;
hitmesh=m;
}
}
e=e->next_elem;
}
if (hitobj)
return 1;
else return 0;
}
float d1=vec_dot(n->normal,p1)+n->d0,
d2=vec_dot(n->normal,p2)+n->d0;
if(d1<-rad && d2<-rad)
if (n->child[1])
return collision_bsp(n->child[1],p1,p2,elemtype,rad);
else return 0;
else
if(d1>rad && d2>rad)
if (n->child[0])
return collision_bsp(n->child[0],p1,p2,elemtype,rad);
else return 0;
else
{
if (d1>0)
{
if (n->child[0])
if (collision_bsp(n->child[0],p1,p2,elemtype,rad))
return 1;
if (n->child[1])
if (collision_bsp(n->child[1],p1,p2,elemtype,rad))
return 1;
}
else
{
if (n->child[1])
if (collision_bsp(n->child[1],p1,p2,elemtype,rad))
return 1;
if (n->child[0])
if (collision_bsp(n->child[0],p1,p2,elemtype,rad))
return 1;
}
return 0;
}
}
void flyEngine::compute_edges()
{
if (edges)
delete edges;
edges=new int[nfaces*3*5];
if (faceedges)
delete faceedges;
faceedges=new int[nfaces*3];
nedges=0;
int i1,i2;
int i,j,nc,k;
for( i=0;i<nfaces;i++ )
for( j=0;j<3;j++ )
{
i1=faces[i].vert[j]-vert;
i2=faces[i].vert[(j+1)%3]-vert;
nc=0;
for( k=0;k<nedges;k++,nc+=5 )
if ((i1==edges[nc] && i2==edges[nc+1]) ||
(i1==edges[nc+1] && i2==edges[nc]))
break;
if (k==nedges)
{
edges[nc]=i1;
edges[nc+1]=i2;
edges[nc+2]=i;
edges[nc+3]=-1;
edges[nc+4]=0;
faceedges[i*3+j]=nedges;
nedges++;
}
else
{
faceedges[i*3+j]=k;
if ((faces[i].color-faces[edges[nc+2]].color).length()<0.1f)
edges[nc+3]=i;
}
}
}
void flyEngine::draw_bsp(int mode)
{
nodedrawcount=0;
nelemdraw=0;
memset(nelemlatedraw,0,sizeof(int)*MAX_LATEDRAW_LAYERS);
nfacedraw=0;
nfacedrawtransp=0;
draw_bsp(bsp);
if (mode)
{
if (edges==0)
compute_edges();
draw_static_faces_cartoon(facedraw,nfacedraw);
draw_bsp_edges();
}
else
{
if (nfacedraw)
draw_static_faces(facedraw,nfacedraw);
if (nfacedrawtransp)
draw_static_faces(facedrawtransp,nfacedrawtransp);
}
int i,j;
for( i=0;i<nelemdraw;i++ )
elemdraw[i]->draw();
for( j=0;j<MAX_LATEDRAW_LAYERS;j++ )
for( i=0;i<nelemlatedraw[j];i++ )
elemlatedraw[j][i]->draw();
}
void flyEngine::draw_bsp(bsp_node *n)
{
if (n->leaf!=-1)
{
if (cam->node==0 || (nodeonly && n!=cam->node))
return;
if (pvsoff || PVS_TEST(cam->node->leaf,n->leaf))
{
bsp_object *e=n->elem;
while(e)
{
if (e->type==TYPE_STATIC_MESH)
{
static_mesh *o=(static_mesh *)e;
o->objmesh->lastdraw=cur_frame;
for( int i=0;i<o->objmesh->nf;i++ )
if (o->objmesh->faces[i]->lastdraw!=cur_frame)
{
if (FP_BITS(o->objmesh->faces[i]->color.w)==FP_ONE_BITS)
facedraw[nfacedraw++]=o->objmesh->faces[i]->indx;
else if (FP_BITS(o->objmesh->faces[i]->color.w)!=0)
facedrawtransp[nfacedrawtransp++]=o->objmesh->faces[i]->indx;
o->objmesh->faces[i]->lastdraw=cur_frame;
}
}
else
elemlatedraw[e->latedraw&7][nelemlatedraw[e->latedraw&7]++]=e;
e=e->next_elem;
}
nodedrawcount++;
}
return;
}
float x1,x2;
int i;
x1=n->distance(frustrum[0]);
for( i=1;i<5;i++ )
{
x2=n->distance(frustrum[i]);
if (x1*x2<=0)
break;
}
if (i==5)
if (x1>0)
{
if (n->child[0])
draw_bsp(n->child[0]);
}
else
{
if (n->child[1])
draw_bsp(n->child[1]);
}
else
if (x1<0)
{
if (n->child[1])
draw_bsp(n->child[1]);
if (n->child[0])
draw_bsp(n->child[0]);
}
else
{
if (n->child[0])
draw_bsp(n->child[0]);
if (n->child[1])
draw_bsp(n->child[1]);
}
}
int flyEngine::step()
{
static int dt,t0=timeGetTime()-start_time;
// compute elapsed time
cur_time=timeGetTime()-start_time;
dt=cur_time-t0;
if (dt>0)
{
t0=cur_time;
if (dt<1000)
{
step(dt);
return dt;
}
}
return 0;
}
void flyEngine::step(int dt)
{
if (flyengine->player==0 || flyengine->cam==0 || flyengine->bsp==0)
return;
// process console commands
if (flyengine->console_command[0])
{
char *c=flyengine->console_command;
do
{
flyengine->con.command_exec(c);
c=strchr(c,';');
if (c)
*(c++)=0;
}
while(c);
}
flyengine->console_command[0]=0;
int i;
// if not in server mode
if (directx->mpmode!=FLYMP_SERVER)
{
// get input
if (noinput)
{
memset(directx->diks,0,sizeof(directx->diks));
memset(&directx->dims,0,sizeof(directx->dims));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -