STEP 1:[cl_main.c,client.h :: set up the variables] -open "cl_main.c" add this at top with other cvar declarations... cvar_t *cl_3dcam; cvar_t *cl_3dcam_angle; cvar_t *cl_3dcam_dist; -then find the function CL_InitLocal() and add this inside...
cl_3dcam = Cvar_Get ("cl_3dcam", "0", CVAR_ARCHIVE);
cl_3dcam_angle = Cvar_Get ("cl_3dcam_angle", "30", CVAR_ARCHIVE);
cl_3dcam_dist = Cvar_Get ("cl_3dcam_dist", "50", CVAR_ARCHIVE);
-now go into "client.h" and add this anywhere... extern cvar_t *cl_3dcam; extern cvar_t *cl_3dcam_angle; extern cvar_t *cl_3dcam_dist; STEP 2:[cl_ents.c :: set up the view angles ] -find the "CL_CalcViewValues" function and add this to the bottom of it...
if (cl_3dcam->value)
{
vec3_t end, oldorg, camPos;
float dist_up, dist_back, angle;
if (cl_3dcam_angle->value<0)
Cvar_SetValue( "cl_3dcam_angle", 0 );
if (cl_3dcam_angle->value>60)
Cvar_SetValue( "cl_3dcam_angle", 60 );
if (cl_3dcam_dist->value<0)
Cvar_SetValue( "cl_3dcam_dist", 0 );
//this'll use polar coords for cam offset
angle = M_PI * cl_3dcam_angle->value/180.0f;
dist_up = cl_3dcam_dist->value * sin( angle );
dist_back = cl_3dcam_dist->value * cos ( angle );
VectorCopy(cl.refdef.vieworg, oldorg);
VectorMA(cl.refdef.vieworg, -dist_back, cl.v_forward, end);
VectorMA(end, dist_up, cl.v_up, end);
ClipCam (cl.refdef.vieworg, end, camPos);
//now we will adjust aim...
{
vec3_t newDir, dir;
//find where 1st person view is aiming
VectorMA(cl.refdef.vieworg, 8000, cl.v_forward, dir);
ClipCam (cl.refdef.vieworg, dir, newDir);
VectorSubtract(newDir, camPos, dir);
VectorNormalize(dir);
vectoangles2(dir, newDir);
//now look there from the camera
AngleVectors(newDir, cl.v_forward, cl.v_right, cl.v_up);
VectorCopy(newDir, cl.refdef.viewangles);
}
VectorCopy(camPos, cl.refdef.vieworg);
}
STEP 3:[cl_ents.c :: add client side clipping] -put this at the top of the file after includes and var/function decalarations...
trace_t CL_Trace (vec3_t start, vec3_t end, float size, int contentmask)
{
vec3_t maxs, mins;
VectorSet(maxs, size, size, size);
VectorSet(mins, -size, -size, -size);
return CM_BoxTrace (start, end, mins, maxs, 0, contentmask);
}
void ClipCam (vec3_t start, vec3_t end, vec3_t newpos)
{
trace_t tr = CL_Trace (start, end, 5, -1);
VectorCopy(tr.endpos, newpos);
}
STEP 4:[cl_ents.c :: remove the 1st person model] -put this at the top of the "void CL_AddViewWeapon(*,*)" function after variable declarations... //dont draw if outside body... if (cl_3dcam->value) return; STEP 5:[cl_ents.c :: add the client model to the render list] -find the funtion void "CL_AddPacketEntities(*)" -find this line... for (pnum = 0 ; pnum -and add this right after it... qboolean isclientviewer = false; -now replace this...
if (s1->number == cl.playernum+1)
{
ent.flags |= RF_VIEWERMODEL; // only draw from mirrors
// FIXME: still pass to refresh
if (effects & EF_FLAG1)
V_AddLight (ent.origin, 225, 1.0, 0.1, 0.1);
else if (effects & EF_FLAG2)
V_AddLight (ent.origin, 225, 0.1, 0.1, 1.0);
else if (effects & EF_TAGTRAIL) //PGM
V_AddLight (ent.origin, 225, 1.0, 1.0, 0.0); //PGM
else if (effects & EF_TRACKERTRAIL) //PGM
V_AddLight (ent.origin, 225, -1.0, -1.0, -1.0); //PGM
continue;
}
-with this...
if (s1->number == cl.playernum+1)
{
ent.flags |= RF_VIEWERMODEL; // only draw from mirrors
isclientviewer = true;
// FIXME: still pass to refresh
if (effects & EF_FLAG1)
V_AddLight (ent.origin, 225, 1.0, 0.1, 0.1);
else if (effects & EF_FLAG2)
V_AddLight (ent.origin, 225, 0.1, 0.1, 1.0);
else if (effects & EF_TAGTRAIL) //PGM
V_AddLight (ent.origin, 225, 1.0, 1.0, 0.0); //PGM
else if (effects & EF_TRACKERTRAIL) //PGM
V_AddLight (ent.origin, 225, -1.0, -1.0, -1.0); //PGM
if (!cl_3dcam->value)
continue;
}
-now after this line...
if (s1->modelindex2)
{
-add this... if (isclientviewer) ent.flags |= RF_VIEWERMODEL; // only draw from mirrors -also after this...
if (s1->modelindex3)
{
-add this.. if (isclientviewer) ent.flags |= RF_VIEWERMODEL; // only draw from mirrors -and lastly after this...
if (s1->modelindex4)
{
add this again... if (isclientviewer) ent.flags |= RF_VIEWERMODEL; // only draw from mirrors STEP 6:[cl_view.c :: make the 3rd person model visible] -find the funtion void "V_AddEntity(*)" -add this in at the top of the function...
if (ent->flags&RF_VIEWERMODEL) //here is our client
{
int i;
for (i=0;i<3;i++)
ent->oldorigin[i] = ent->origin[i] = cl.predicted_origin[i];
if (cl_3dcam->value)
ent->flags&=~RF_VIEWERMODEL;
}
STEP 7:[cl_ents.c :: smooth out prediction] -find the funtion void "CL_CalcViewValues()" -replace this...
// calculate the origin
if ((cl_predict->value) && !(cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION))
{ // use predicted values
unsigned delta;
backlerp = 1.0 - lerp;
for (i=0 ; i<3 ; i++)
{
cl.refdef.vieworg[i] = cl.predicted_origin[i] + ops->viewoffset[i]
+ cl.lerpfrac * (ps->viewoffset[i] - ops->viewoffset[i])
- backlerp * cl.prediction_error[i];
}
// smooth out stair climbing
delta = cls.realtime - cl.predicted_step_time;
if (delta < 100)
{
cl.refdef.vieworg[2] -= cl.predicted_step * (100 - delta) * 0.01;
}
}
-with this (adding in cl.predicted_origin[] smoothing)...
// calculate the origin
if ((cl_predict->value) && !(cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION))
{ // use predicted values
unsigned delta;
backlerp = 1.0 - lerp;
for (i=0 ; i<3 ; i++)
{
cl.refdef.vieworg[i] = cl.predicted_origin[i] + ops->viewoffset[i]
+ cl.lerpfrac * (ps->viewoffset[i] - ops->viewoffset[i])
- backlerp * cl.prediction_error[i];
//this smooths out platform riding
cl.predicted_origin[i] -= backlerp * cl.prediction_error[i];
}
// smooth out stair climbing
delta = cls.realtime - cl.predicted_step_time;
if (delta < 100)
{
cl.refdef.vieworg[2] -= cl.predicted_step * (100 - delta) * 0.01;
cl.predicted_origin[2] -= cl.predicted_step * (100 - delta) * 0.01;
}
}
FINISH:[test :: play the game]
- Play with the cvars to get the cam how you like it - Tweak until content |