📄 car.cpp
字号:
{
// normalize velocity
vel/=len;
if (len>maxvel)
len=maxvel;
// project velocity in car local axes
v.x=vec_dot(vel,X)*len;
v.y=vec_dot(vel,Y)*len;
v.z=vec_dot(vel,Z)*len;
// apply damping to individual axes
// X for sliding and Z for breaking
for( int i=0;i<3;i++ )
if (v[i]>=0.0f)
{
v[i]-=veldamp[i]*dt;
if (v[i]<0.0) v[i]=0.0f;
}
else
{
v[i]+=veldamp[i]*dt;
if (v[i]>0.0) v[i]=0.0f;
}
// restore velocity vector from axes components
vel=X*v.x + Y*v.y + Z*v.z;
// compute wheel roll based on forward motion and wheel radius
wheelroll+=v.z*dt/(M_2Pi*wheelradius)*360.0f;
wheelroll=(float)fmod(wheelroll,360);
// move by applying the car velocity
p=pos+vel*(float)dt;
flyengine->excludecollision=this;
if (flyengine->collision_bsp(flyengine->bsp,pos,p))
{
contactobj=flyengine->hitmesh;
contactfacenum=flyengine->hitface;
}
else contactobj=0;
flyengine->excludecollision=0;
if (contactobj)
pos=flyengine->hitip+contactobj->faces[contactfacenum]->normal*carheight;
else pos=p;
}
else v.null();
if (contactobj==0)
{
// ray intesect collision detection to check for ground contact
p=pos-Y*carheight;
flyengine->excludecollision=this;
if (flyengine->collision_bsp(flyengine->bsp,pos,p))
{
contactobj=flyengine->hitmesh;
contactfacenum=flyengine->hitface;
}
else contactobj=0;
flyengine->excludecollision=0;
}
// if in contact
if (contactobj)
{
// position the car at a fixed distance from the ground
pos=flyengine->hitip+Y*(carheight-0.1f);
// align car with ground if no collision with wall
if (contactobj->localfaces==0 && contactobj->faces[contactfacenum]->normal.z<0.5f)
{
rotate(Y,vector(0,0,1));
v.z=-v.z;
v.x=-v.x;
}
else rotate(Y,contactobj->faces[contactfacenum]->normal,0.1f*dt);
// recompute velocity
vel=X*v.x + Y*v.y + Z*v.z;
// rotate car body based on forward motion and steering angle if in contact
rotate(-wheelrot*v.z*dt/carwheelrot,Y);
}
return 1;
}
void car::check_keys(int dt)
{
unsigned char *diks=directx->diks;
if (diks[0xcb]) // left arrow
wheelrot+=wheelrotvel*dt;
if (diks[0xcd]) // right arrow
wheelrot-=wheelrotvel*dt;
if (contactobj)
{
if (diks[0xc8]) // up arrow
vel-=Z*(accel*dt);
if (diks[0xd0]) // down arrow
vel+=Z*(accel*dt);
}
}
void car::check_robot_keys(int dt)
{
if (track==0)
return;
vector P,T,V;
float len,dot;
// get position of rabbit
curtracktime=(curtracktime+dt)%totaltracktime;
track->evaluate((float)curtracktime/totaltracktime,&P.x);
P.z+=track->pivot.z-50;
T=P-pos;
len=T.length();
T/=len;
dot=vec_dot(T,Z);
if (dot<0.996) // 0.996=cosd(8)
{
V.cross(T,Z);
if (vec_dot(V,Y)>0)
wheelrot+=wheelrotvel*dt; // rotate right
else
wheelrot-=wheelrotvel*dt; // rotate left
}
if (contactobj)
if (len>500)
vel-=Z*(accel*dt); // move forward
}
void car::mp_send_pos(int msgtype,int msgflag)
{
static struct mp_data data;
data.type=msgtype;
data.dpid=directx->players[player].dpid;
data.flag=msgflag;
data.pos=pos;
data.vel=vel;
data.Y=Y;
data.Z=Z;
data.wheelrot=wheelrot;
directx->send_message((mp_msg *)&data,sizeof(struct mp_data));
}
void mp_message(int from,mp_msg *msg)
{
switch( msg->type )
{
case FLYMP_MSG_POS:
{
mp_data *data=(mp_data *)&msg->type;
car *c=(car *)directx->players[from].data;
if (from>0)
{
c->remove_from_bsp();
c->pos=data->pos;
c->vel=data->vel;
c->Y=data->Y;
c->Z=data->Z;
c->X.cross(c->Y,c->Z);
c->wheelrot=data->wheelrot;
c->update_mat();
c->add_to_bsp();
}
}
break;
case FLYMP_MSG_JOIN:
{
player_data *data=(player_data *)&msg->type;
car *c=(car *)flyengine->player->clone();
c->player=directx->add_player(data->name,data->dpid,c);
flyengine->set_status_msg("%s HAS JOINED THE GAME",data->name);
flyengine->activate(c,(directx->mpmode==FLYMP_SERVER));
}
break;
case FLYMP_MSG_QUIT:
{
player_data *data=(player_data *)&msg->type;
if (from<directx->nplayers)
{
flyengine->set_status_msg("%s HAS LEFT THE GAME",directx->players[from].name);
bsp_object *obj=(bsp_object *)directx->remove_player(from);
for( int i=from;i<directx->nplayers;i++ )
((car *)directx->players[i].data)->player=i;
if (obj) obj->life=-1;
}
}
break;
}
}
bsp_object *camera::clone()
{
camera *tmp=new camera;
*tmp=*this;
tmp->source=this;
return tmp;
}
int camera::get_custom_param_desc(int i,param_desc *pd)
{
if (pd!=0)
switch(i)
{
case 0:
pd->type='f';
pd->data=&height;
strcpy(pd->name,"height");
break;
case 1:
pd->type='f';
pd->data=&dist;
strcpy(pd->name,"dist");
break;
case 2:
pd->type='d';
pd->data=⌖
strcpy(pd->name,"target");
break;
case 3:
pd->type='f';
pd->data=&maxvel;
strcpy(pd->name,"maxvel");
break;
case 4:
pd->type=TYPE_SUN;
pd->data=&s;
strcpy(pd->name,"sun");
break;
}
return 5;
}
void camera::init()
{
if (target)
{
lp=target->pos;
pos=target->source->pos;
}
}
int camera::step(int dt)
{
vector dir,p;
if (target)
{
dir.x=target->pos.x-pos.x;
dir.y=target->pos.y-pos.y;
dir.z=0;
dir.normalize();
p.x=target->pos.x-dir.x*dist;
p.y=target->pos.y-dir.y*dist;
p.z=target->pos.z+height;
float dist;
dir=p-pos;
dist=dir.length();
if (dist>0.01f)
{
dir/=dist;
if (dist>maxvel*dt)
dist=maxvel*dt;
pos+=dir*dist;
}
if (flyengine->collision_bsp(flyengine->bsp,pos,vector(pos.x,pos.y,pos.z-flyengine->viewmindist*2)))
pos.vec(flyengine->hitip.x,flyengine->hitip.y,flyengine->hitip.z+flyengine->viewmindist*2);
dir=target->pos-lp;
dist=dir.length();
if (dist>0.01f)
{
dir/=dist;
if (dist>maxvel*dt)
dist=maxvel*dt;
lp+=dir*dist;
}
dir=pos-lp;
dir.normalize();
align_z(dir);
}
return 1;
}
bsp_object *sun::clone()
{
sun *tmp=new sun;
*tmp=*this;
tmp->source=this;
return tmp;
}
int sun::get_custom_param_desc(int i,param_desc *pd)
{
if (pd!=0)
switch(i)
{
case 0:
pd->type='3';
pd->data=&objmesh;
strcpy(pd->name,"objmesh");
break;
case 1:
pd->type='c';
pd->data=&color;
strcpy(pd->name,"color");
break;
case 2:
pd->type='f';
pd->data=&color.w;
strcpy(pd->name,"transp");
break;
case 3:
pd->type='p';
pd->data=&halopic;
strcpy(pd->name,"halopic");
break;
case 4:
pd->type='f';
pd->data=&halosize;
strcpy(pd->name,"halosize");
break;
}
return 5;
}
void sun::init()
{
if (objmesh)
pos=objmesh->pivotpos;
}
void sun::draw()
{
static vector x,y;
int d=(int)(pos-flyengine->cam->pos).length()/10*10;
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
gluPerspective( flyengine->camangle, flyengine->aspect, d/2,2*d);
glMatrixMode( GL_MODELVIEW );
glDisable(GL_FOG);
glDisable(GL_DEPTH_TEST);
glPushMatrix();
glTranslatef(pos.x,pos.y,pos.z);
if (objmesh)
objmesh->draw();
x=flyengine->cam->X*halosize;
y=flyengine->cam->Y*halosize;
glBlendFunc(GL_ONE,GL_ONE);
glDepthMask(GL_FALSE);
glColor3f(color.x*color.w,color.y*color.w,color.z*color.w);
tc->use(halopic);
glBegin(GL_QUADS);
glTexCoord2f(1,0);
glVertex3f(x.x-y.x, x.y-y.y, x.z-y.z);
glTexCoord2f(1,1);
glVertex3f(x.x+y.x, x.y+y.y, x.z+y.z);
glTexCoord2f(0,1);
glVertex3f(y.x-x.x, y.y-x.y, y.z-x.z);
glTexCoord2f(0,0);
glVertex3f(-x.x-y.x, -x.y-y.y, -x.z-y.z);
glEnd();
glPopMatrix();
glDepthMask(GL_TRUE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_DEPTH_TEST);
if (flyengine->fog) glEnable(GL_FOG);
glMatrixMode( GL_PROJECTION );
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -