📄 flyengine.cpp
字号:
else directx->get_input();
// attebuate filter
if (FP_BITS(filter.x)!=0)
{
filter.x-=dt/500.0f;
if (FP_SIGN_BIT(filter.x)) filter.x=0;
}
if (FP_BITS(filter.y)!=0)
{
filter.y-=dt/500.0f;
if (FP_SIGN_BIT(filter.y)) filter.y=0;
}
if (FP_BITS(filter.z)!=0)
{
filter.z-=dt/500.0f;
if (FP_SIGN_BIT(filter.z)) filter.z=0;
}
// if a texture cache available
if (tc)
for( i=0;i<nlm;i++ )
{
// update changed lightmaps
if (lm[i]->lastupdate)
{
lm[i]->load(lmpic[lm[i]->pic]);
lm[i]->lastupdate=-1;
}
// update changed fogmaps
if (fm[i]->lastupdate)
{
memset(fm[i]->bmp,0,fm[i]->bytesxy);
fm[i]->lastupdate=-1;
}
}
}
bsp_object *o=active_obj0,*op=0;
cur_step_base=cur_step+1;
cur_dt=dt;
// loop all active objects
while(o)
{
stepobj=o;
// if object life is negative, destroy it
if (o->life<0)
{
if (last_active_obj==o)
last_active_obj=op;
bsp_object *n=(bsp_object *)o->next_obj;
delete o;
if (op==0)
active_obj0=n;
else op->next_obj=n;
o=n;
continue;
}
else
{
// step object and reposition in bsp if needed
cur_step++;
if (o->step(dt))
if (o->node)
{
o->remove_from_bsp();
o->add_to_bsp();
}
}
op=o;
o=(bsp_object *)o->next_obj;
}
stepobj=0;
// if a texture cache is available and not in server mode
if (tc && directx->mpmode!=FLYMP_SERVER)
{
for( i=0;i<nlm;i++ )
{
// update changed lightmap
if (lm[i]->lastupdate)
{
if (lm[i]->lastupdate==-1)
lm[i]->lastupdate=0;
tc->update_sub_picture(
lm[i]->pic+lmbase,lm[i]->offsetx,lm[i]->offsety,
lm[i]->sizex,lm[i]->sizey,3,lm[i]->bmp);
}
// update changed fogmap
if (fm[i]->lastupdate)
{
if (fm[i]->lastupdate==-1)
fm[i]->lastupdate=0;
tc->update_sub_picture(
fm[i]->pic+fmbase,fm[i]->offsetx,fm[i]->offsety,
fm[i]->sizex,fm[i]->sizey,4,fm[i]->bmp);
}
}
}
// step all running plugins
dll.send_message(FLYM_UPDATESCENE,dt,0);
// if in multiplayer, check multiplayer messages
if (directx->mpmode!=FLYMP_NOMP)
check_multiplayer();
// if in client multiplayer mode
if (directx->mpmode==FLYMP_CLIENT)
{
// update client objects to server at slower intervals
static int last_mp_update=0;
if (cur_time-last_mp_update>mpdelay)
{
last_mp_update=flyengine->cur_time;
dll.send_message(FLYM_MPUPDATE,0,0);
}
}
// step console
if (con.mode)
con.step(dt);
}
void flyEngine::apply_bsp(bsp_node *n,vector& p,float rad,void *data,void (*func)(void *data,bsp_object *e))
{
if (n->leaf!=-1)
{
if (n->elem)
{
bsp_object *e=n->elem;
rad*=rad;
vector v;
if (e->type==TYPE_STATIC_MESH)
{
func(data,e);
e=e->next_elem;
}
while(e)
{
v.x=e->pos.x-p.x;
v.y=e->pos.y-p.y;
v.z=e->pos.z-p.z;
if (v.x*v.x+v.y*v.y+v.z*v.z<rad)
func(data,e);
e=e->next_elem;
}
}
return;
}
float d=n->distance(p);
if (fabs(d)<rad)
{
if (n->child[0])
apply_bsp(n->child[0],p,rad,data,func);
if (n->child[1])
apply_bsp(n->child[1],p,rad,data,func);
}
else
if (d>0)
{
if (n->child[0])
apply_bsp(n->child[0],p,rad,data,func);
}
else
if (n->child[1])
apply_bsp(n->child[1],p,rad,data,func);
}
void flyEngine::apply_bsp(bsp_node *n,vector *p,int np,void *data,void (*func)(void *data,bsp_object *e))
{
if (n->leaf!=-1)
{
bsp_object *e=n->elem;
while(e)
{
func(data,e);
e=e->next_elem;
}
return;
}
float x1,x2;
int i;
x1=n->distance(p[0]);
for( i=1;i<np;i++ )
{
x2=n->distance(p[i]);
if (x1*x2<=0)
break;
}
if (i==5)
if (x1>0)
{
if (n->child[0])
apply_bsp(n->child[0],p,np,data,func);
}
else
{
if (n->child[1])
apply_bsp(n->child[1],p,np,data,func);
}
else
{
if (n->child[0])
apply_bsp(n->child[0],p,np,data,func);
if (n->child[1])
apply_bsp(n->child[1],p,np,data,func);
}
}
void flyEngine::send_bsp_message(bsp_node *n,vector& p,float rad,int msg,int param,void *data)
{
static float d;
if (n->leaf!=-1)
{
bsp_object *e=n->elem;
while(e)
{
e->message(p,rad,msg,param,data);
e=e->next_elem;
}
return;
}
d=n->distance(p);
if (fabs(d)<rad)
{
if (n->child[0])
send_bsp_message(n->child[0],p,rad,msg,param,data);
if (n->child[1])
send_bsp_message(n->child[1],p,rad,msg,param,data);
}
else
if (d>0)
if (n->child[0])
send_bsp_message(n->child[0],p,rad,msg,param,data);
else ;
else
if (n->child[1])
send_bsp_message(n->child[1],p,rad,msg,param,data);
}
int flyEngine::collision_test(bsp_node *n,vector& p1,vector& p2,int elemtype,float rad)
{
if (n->leaf!=-1)
{
bsp_object *e=n->elem;
while(e)
{
if (e!=excludecollision &&
(elemtype==0 || e->type==elemtype))
if (e->ray_intersect_test(p1,p2-p1,rad))
return 1;
e=e->next_elem;
}
return 0;
}
float d1=vec_dot(n->normal,p1)+n->d0,
d2=vec_dot(n->normal,p2)+n->d0;
if(d1<SMALL && d2<SMALL)
if (n->child[1])
return collision_test(n->child[1],p1,p2,elemtype,rad);
else return 0;
else if(d1>SMALL && d2>SMALL)
if (n->child[0])
return collision_test(n->child[0],p1,p2,elemtype,rad);
else return 0;
else
{
if (n->child[0])
if (collision_test(n->child[0],p1,p2,elemtype,rad))
return 1;
if (n->child[1])
if (collision_test(n->child[1],p1,p2,elemtype,rad))
return 1;
return 0;
}
}
void flyEngine::find_leaf(bsp_node *n)
{
if (n->child[0]==0 && n->child[1]==0)
{
if (n->leaf!=-1)
if (leaf)
leaf[n->leaf]=n;
else nleaf++;
return;
}
n->leaf=-1;
if (n->child[0])
find_leaf(n->child[0]);
if (n->child[1])
find_leaf(n->child[1]);
}
void flyEngine::alloc_pvs(char value)
{
if (pvs)
delete pvs;
pvs=0;
pvssize=0;
pvsrowsize=0;
if (leaf)
delete leaf;
leaf=0;
nleaf=0;
if (bsp)
{
find_leaf(bsp);
if (nleaf==0)
return;
leaf=new bsp_node *[nleaf];
memset(leaf,0,nleaf*sizeof(bsp_node *));
find_leaf(bsp);
}
if (nleaf)
{
pvsrowsize=nleaf/8+1;
if (pvsrowsize&3)
pvsrowsize+=4-(pvsrowsize&3);
pvssize=pvsrowsize*nleaf;
pvs=new char[pvssize];
memset(pvs,value,pvssize);
}
}
bsp_node *flyEngine::find_node(bsp_node *n,vector& v,float mindist)
{
float dist;
while(n->child[0]!=0 || n->child[1]!=0)
{
dist=n->distance(v);
if (fabs(dist)<mindist)
return 0;
if (dist>=0)
if (n->child[0])
n=n->child[0];
else return 0;
else if (n->child[1])
n=n->child[1];
else return 0;
}
return n;
}
bsp_node *flyEngine::get_random_point(vector& v,float mindist)
{
if (bsp==0)
{
v.null();
return 0;
}
vector diag=bbox2-bbox1;
bsp_node *n;
int maxpoints=100;
new_point:
if (--maxpoints==0)
{
v.null();
return 0;
}
v.x=bbox1.x+FABSRAND*diag.x;
v.y=bbox1.y+FABSRAND*diag.y;
v.z=bbox1.z+FABSRAND*diag.z;
n=find_node(bsp, v, mindist);
if (n==0 || n->leaf==-1)
goto new_point;
return n;
}
void flyEngine::set_status_msg(char *fmt, ...)
{
char ach[128];
va_list va;
va_start( va, fmt );
wvsprintf( ach, fmt, va );
va_end( va );
strcpy(status_msg,ach);
status_msg_time=cur_time;
con.add_string(ach);
}
void flyEngine::activate(bsp_object *d,int flag)
{
if (bsp==0 || d==0)
return;
d->next_obj=0;
if (last_active_obj)
last_active_obj->next_obj=d;
else
active_obj0=d;
last_active_obj=d;
d->node=0;
if (flag)
d->add_to_bsp();
}
int flyEngine::open_fly_file(char *file)
{
char str[256];
close_fly_file();
strcpy(str,file);
strlwr(str);
strcpy(flyfile,str);
strcpy(flydatapath,flysdkpath);
strcat(flydatapath,"data\\");
strcpy(flyfilename,flydatapath);
strcat(flyfilename,flyfile);
char *c=strrchr(str,'\\');
if (c==0) c=strrchr(str,'/');
if (c) { *(c+1)=0; strcat(flydatapath,str); }
if (load_data()==0)
{
reset();
return 0;
}
init_texture_cache();
return 1;
}
int flyEngine::save_fly_file(char *file)
{
strlwr(file);
strcpy(flyfile,file);
strcpy(flydatapath,flysdkpath);
strcat(flydatapath,"data\\");
strcpy(flyfilename,flydatapath);
strcat(flyfilename,flyfile);
char *c=strrchr(file,'\\');
if (c==0) c=strrchr(file,'/');
if (c) { *(c+1)=0; strcat(flydatapath,file); }
FILE *fp=fopen(flyfilename,"wt");
if (fp==0)
{
flydatapath[0]=0;
flyfilename[0]=0;
flyfile[0]=0;
return 0;
}
char *name;
int i,j,n,type;
bsp_object *o;
param_desc pd;
fprintf(fp,"[classes]\n");
for( i=0;i<dll.ndll;i++ )
fprintf(fp,"dll%i=%s\n",i,dll.dll[i]->dll_filename);
for( i=0;i<dll.ncd;i++ )
{
name=dll.cd[i]->get_name();
type=dll.cd[i]->get_type();
o=stock_obj0;
n=0;
while(o)
{
if (o->type==type)
sprintf(o->name,"%s%i",name,n++);
o=(bsp_object *)o->next_obj;
}
}
o=active_obj0;
while(o)
{
if (o->source)
strcpy(o->name,o->source->name);
o=(bsp_object *)o->next_obj;
}
for( i=0;i<dll.ncd;i++ )
{
name=dll.cd[i]->get_name();
type=dll.cd[i]->get_type();
o=stock_obj0;
n=0;
while(o)
{
if (o->type==type)
{
fprintf(fp,"\n");
fprintf(fp,"[%s]\nlongname=%s\n",o->name,o->long_name);
n=o->get_param_desc(0,0);
for( j=0;j<n;j++ )
{
o->get_param_desc(j,&pd);
fprintf(fp,"%s=%s\n",pd.name,pd.get_string());
}
}
o=(bsp_object *)o->next_obj;
}
}
fprintf(fp,"\n");
fprintf(fp,"[fly]\n");
n=get_global_param_desc(0,0);
for( i=0;i<n;i++ )
{
get_global_param_desc(i,&pd);
if (pd.type!=' ')
fprintf(fp,"%s=%s\n",pd.name,pd.get_string());
}
fclose(fp);
return 1;
}
void flyEngine::close_fly_file()
{
dll.send_message(FLYM_CLOSESCENE,0,0);
close_texture_cache();
reset();
}
void flyEngine::init_texture_cache()
{
if (rend==0)
return;
if (tc) delete tc;
tc=new textcacheGL();
tc->init(npiclib,piclib);
int i;
lmbase=tc->npic;
for( i=0;i<nlmpic;i++ )
tc->add_picture(lmpic[i]->sizex,lmpic[i]->sizey,3,lmpic[i]->bmp);
fmbase=tc->npic;
for( i=0;i<nlmpic;i++ )
tc->add_picture(fmpic[i]->sizex,fmpic[i]->sizey,4,fmpic[i]->bmp);
}
void flyEngine::close_texture_cache()
{
if (tc) delete tc;
tc=0;
}
void flyEngine::set_camera(bsp_object *d)
{
cam=d;
float disty=viewmaxdist*(float)tan(camangle*0.5f*PiOver180);
float distx=disty*aspect;
if (cam)
{
frustrum[0]=cam->pos;
frustrum[1].x = cam->pos.x - viewmaxdist*cam->Z.x +
distx*cam->X.x + disty*cam->Y.x;
frustrum[1].y = cam->pos.y - viewmaxdist*cam->Z.y +
distx*cam->X.y + disty*cam->Y.y;
frustrum[1].z = cam->pos.z - viewmaxdist*cam->Z.z +
distx*cam->X.z + disty*cam->Y.z;
frustrum[2].x = cam->pos.x - viewmaxdist*cam->Z.x +
distx*cam->X.x - disty*cam->Y.x;
frustrum[2].y = cam->pos.y - viewmaxdist*cam->Z.y +
distx*cam->X.y - disty*cam->Y.y;
frustrum[2].z = cam->pos.z - viewmaxdist*cam->Z.z +
distx*cam->X.z - disty*cam->Y.z;
frustrum[3].x = cam->pos.x - viewmaxdist*cam->Z.x -
distx*cam->X.x - disty*cam->Y.x;
frustrum[3].y = cam->pos.y - viewmaxdist*cam->Z.y -
distx*cam->X.y - disty*cam->Y.y;
frustrum[3].z = cam->pos.z - viewmaxdist*cam->Z.z -
distx*cam->X.z - disty*cam->Y.z;
frustrum[4].x = cam->pos.x - viewmaxdist*cam->Z.x -
distx*cam->X.x + disty*cam->Y.x;
frustrum[4].y = cam->pos.y - viewmaxdist*cam->Z.y -
distx*cam->X.y + disty*cam->Y.y;
frustrum[4].z = cam->pos.z - viewmaxdist*cam->Z.z -
distx*cam->X.z + disty*cam->Y.z;
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( flyengine->camangle, flyengine->aspect, flyengine->viewmindist,flyengine->viewmaxdist*1.5f);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glMultMatrixf((float *)&cam->mat_t);
glTranslatef(-cam->pos.x,-cam->pos.y,-cam->pos.z);
}
}
int flyEngine::get_picture(char *file)
{
if (file[0]==0)
return -1;
int j;
for( j=0;j<npiclib;j++ )
if (!stricmp(piclib[j]->name,file))
break;
if (j==npiclib)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -