⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flyengine.cpp

📁 是3D游戏一书中所讲的游戏引擎fly3D 包括fly3D引擎的源码及应用此引擎开发出来的游戏实例 有fly3D引擎的教程,易于step by step跟学
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	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 + -