/* A moving object that doesn't obey physics */ void Physics_NoClip(edict_t *eEntity) { // Regular thinking if(!Server_RunThink(eEntity)) return; Math_VectorMA(eEntity->v.angles,host_frametime,eEntity->v.avelocity,eEntity->v.angles); Math_VectorMA(eEntity->v.origin,host_frametime,eEntity->v.velocity,eEntity->v.origin); SV_LinkEdict(eEntity,false); }
/* The mouse click did not hit the brush, so grab one or more side planes for dragging */ void Brush_SideSelect(brush_t *b,vec3_t origin,vec3_t dir,bool shear) { face_t *f, *f2; vec3_t p1, p2; for(f = b->brush_faces; f; f = f->next) { Math_VectorCopy(origin,p1); Math_VectorMA(origin,16384,dir,p2); for (f2=b->brush_faces ; f2 ; f2=f2->next) { if (f2 == f) continue; Brush_ClipLineToFace(p1,p2,f2); } if(f2) continue; if(Math_VectorCompare(p1,origin)) continue; if(Brush_ClipLineToFace(p1,p2,f)) continue; Brush_SelectFaceForDragging (b, f, shear); } }
// TODO: stay at least 8 units away from all walls in this leaf void Chase_UpdateForDrawing (void) { int i; vec3_t forward, up, right; vec3_t ideal, crosshair, temp; Math_AngleVectors(cl.viewangles, forward, right, up); // calc ideal camera location before checking for walls for (i=0 ; i<3 ; i++) ideal[i] = cl.viewent.origin[i] - forward[i]*chase_back.value + right[i]*chase_right.value; //+ up[i]*chase_up.value; ideal[2] = cl.viewent.origin[2] + chase_up.value; // make sure camera is not in or behind a wall TraceLine(r_refdef.vieworg, ideal, temp); if(Math_Length(temp) != 0) Math_VectorCopy(temp, ideal); // place camera Math_VectorCopy(ideal, r_refdef.vieworg); // find the spot the player is looking at Math_VectorMA(cl.viewent.origin, 4096, forward, temp); TraceLine(cl.viewent.origin, temp, crosshair); // calculate camera angles to look at the same spot Math_VectorSubtract(crosshair,r_refdef.vieworg,temp); Math_VectorAngles (temp, r_refdef.viewangles); if (r_refdef.viewangles[PITCH] == 90 || r_refdef.viewangles[PITCH] == -90) r_refdef.viewangles[YAW] = cl.viewangles[YAW]; }
/* Player character actions */ void SV_Physics_Client (edict_t *ent, int num) { if(!svs.clients[num-1].active) return; // unconnected slot // call standard client pre-think pr_global_struct.self = EDICT_TO_PROG(ent); Game->Game_Init(SERVER_PLAYERPRETHINK,ent,sv.time); Game->Physics_CheckVelocity(ent); // decide which move function to call switch(ent->v.movetype) { case MOVETYPE_NONE: if (!Server_RunThink(ent)) return; break; case MOVETYPE_WALK: if(!Server_RunThink(ent)) return; if(!Physics_CheckWater(ent) && !(ent->v.flags & FL_WATERJUMP)) Game->Physics_SetGravity(ent); SV_CheckStuck (ent); SV_WalkMove (ent); break; case MOVETYPE_TOSS: case MOVETYPE_BOUNCE: case MOVETYPE_FLYBOUNCE: Physics_Toss(ent); break; case MOVETYPE_FLY: if(!Server_RunThink(ent)) return; SV_FlyMove(ent,host_frametime,NULL); break; case MOVETYPE_NOCLIP: if(!Server_RunThink(ent)) return; Math_VectorMA (ent->v.origin, host_frametime, ent->v.velocity, ent->v.origin); break; default: Sys_Error ("SV_Physics_client: bad movetype %i", (int)ent->v.movetype); } // Call standard player post-think SV_LinkEdict(ent,true); pr_global_struct.self = EDICT_TO_PROG(ent); Game->Game_Init(SERVER_CLIENTPOSTTHINK,ent,sv.time); }
/* Toss, bounce, and fly movement. When onground, do nothing. */ void Physics_Toss(edict_t *ent) { trace_t trace; vec3_t move; float backoff; // Regular thinking if(!Server_RunThink(ent) || (ent->v.flags & FL_ONGROUND)) return; Game->Physics_CheckVelocity(ent); // Add gravity if(ent->v.movetype != MOVETYPE_FLY && ent->v.movetype != MOVETYPE_FLYMISSILE && ent->v.movetype != MOVETYPE_FLYBOUNCE) Game->Physics_SetGravity(ent); // Move angles Math_VectorMA(ent->v.angles,host_frametime,ent->v.avelocity,ent->v.angles); // Move origin Math_VectorScale(ent->v.velocity,host_frametime,move); trace = SV_PushEntity(ent, move); if(trace.fraction == 1.0f || ent->free) return; if(ent->v.movetype == MOVETYPE_FLYBOUNCE) backoff = 2.0f; else if (ent->v.movetype == MOVETYPE_BOUNCE) backoff = 1.5f; else backoff = 1.0f; ClipVelocity (ent->v.velocity, trace.plane.normal, ent->v.velocity, backoff); // Stop if on ground if(trace.plane.normal[2] > 0.7 || (ent->v.movetype != MOVETYPE_BOUNCE && ent->v.movetype != MOVETYPE_FLYBOUNCE)) if(ent->v.velocity[2] < 60.0f) { ent->v.flags = ent->v.flags | FL_ONGROUND; ent->v.groundentity = trace.ent; Math_VectorCopy(mv3Origin,ent->v.velocity); Math_VectorCopy(mv3Origin,ent->v.avelocity); } Game->Physics_CheckWaterTransition(ent); }
winding_t *BasePolyForPlane (plane_t *p) { int i, x; vec_t max, v; vec3_t org, vright, vup; winding_t *w; // find the major axis max = -BOGUS_RANGE; x = -1; for (i=0 ; i<3; i++) { v = fabs(p->normal[i]); if (v > max) { x = i; max = v; } } if (x==-1) Error("BasePolyForPlane: no axis found"); Math_VectorCopy(vec3_origin,vup); switch (x) { case 0: case 1: vup[2] = 1; break; case 2: vup[0] = 1; break; } v = Math_DotProduct(vup,p->normal); Math_VectorMA(vup,-v,p->normal,vup); Math_VectorNormalize(vup); Math_VectorScale(p->normal,p->dist,org); Math_CrossProduct(vup,p->normal,vright); Math_VectorScale(vup,8192,vup); Math_VectorScale(vright,8192,vright); // project a really big axis aligned box onto the plane w = NewWinding (4); Math_VectorSubtract(org,vright,w->points[0]); Math_VectorAdd(w->points[0],vup,w->points[0]); Math_VectorAdd(org,vright,w->points[1]); Math_VectorAdd(w->points[1],vup,w->points[1]); Math_VectorAdd(org,vright,w->points[2]); Math_VectorSubtract(w->points[2],vup,w->points[2]); Math_VectorSubtract(org,vright,w->points[3]); Math_VectorSubtract(w->points[3],vup,w->points[3]); w->numpoints = 4; return w; }
void R_RenderView (void) { double time1 = 0, time2; if (r_norefresh.value) return; if (!cl.worldmodel) Sys_Error ("R_RenderView: NULL worldmodel"); if(r_speeds.value) { glFinish (); time1 = System_DoubleTime(); //johnfitz -- rendering statistics rs_brushpolys = rs_aliaspolys = rs_skypolys = rs_particles = rs_fogpolys = rs_megatexels = rs_dynamiclightmaps = rs_aliaspasses = rs_skypasses = rs_brushpasses = 0; } R_SetupView (); //johnfitz -- this does everything that should be done once per frame Video_ClearBuffer(); //johnfitz -- stereo rendering -- full of hacky goodness if (r_stereo.value) { float eyesep = Math_Clamp(-8.0f, r_stereo.value, 8.0f), fdepth = Math_Clamp(32.0f, r_stereodepth.value, 1024.0f); Math_AngleVectors(r_refdef.viewangles, vpn, vright, vup); // Render left eye (red) glColorMask(true,false,false,true); Math_VectorMA (r_refdef.vieworg, -0.5f * eyesep, vright, r_refdef.vieworg); frustum_skew = 0.5f*eyesep*NEARCLIP/fdepth; srand((int) (cl.time * 1000)); //sync random stuff between eyes R_RenderScene(); // Render right eye (cyan) glClear (GL_DEPTH_BUFFER_BIT); glColorMask(0, 1, 1, 1); Math_VectorMA (r_refdef.vieworg, 1.0f * eyesep, vright, r_refdef.vieworg); frustum_skew = -frustum_skew; srand((int) (cl.time * 1000)); //sync random stuff between eyes R_RenderScene(); // Restore glColorMask(true,true,true,true); Math_VectorMA (r_refdef.vieworg, -0.5f * eyesep, vright, r_refdef.vieworg); frustum_skew = 0.0f; } else R_RenderScene(); //johnfitz //johnfitz -- modified r_speeds output time2 = System_DoubleTime(); if(r_speeds.value == 2) Con_Printf( "%3i ms %4i/%4i wpoly %4i/%4i epoly %3i lmap %4i/%4i sky %1.1f mtex\n", (int)((time2-time1)*1000), rs_brushpolys, rs_brushpasses, rs_aliaspolys, rs_aliaspasses, rs_dynamiclightmaps, rs_skypolys, rs_skypasses, TexMgr_FrameUsage ()); else if(r_speeds.value) Con_Printf ("%3i ms %4i wpoly %4i epoly %3i lmap\n", (int)((time2-time1)*1000), rs_brushpolys, rs_aliaspolys, rs_dynamiclightmaps); //johnfitz }