ANGLE vecChaseAngOff; // angle of the chase camera
var vecChaseOffset[3]= {-150,0,60}; // position of the camera in relation to the chassis center (chase)
var cameraTPos[3]; // camera target position
var cameraTAng[3]; // camera target angle
VECTOR temp, temp2;
var linSpeed; // car speed in XY
ENTITY* pFocus; // the camera will orbit around this entity
....
if (camMode==1) // chase camera?
{
reset(pFocus,INVISIBLE);
if(mouse_right)
{
vecChaseAngOff.pan -= rotspd * mouse_force.x * time_step;
vecChaseAngOff.tilt += rotspd * mouse_force.y * time_step;
vecChaseAngOff.pan = clamp(vecChaseAngOff.pan, -20, 20);
vecChaseAngOff.tilt = clamp(vecChaseAngOff.tilt, -20, 20);
}
else
{
// return to center
if(vecChaseAngOff.pan > 0.25) {vecChaseAngOff.pan -= 2 * time_step; }
if(vecChaseAngOff.pan < -0.25) {vecChaseAngOff.pan += 2 * time_step; }
if(vecChaseAngOff.tilt > 6) {vecChaseAngOff.tilt -= 2 * time_step; }
if(vecChaseAngOff.tilt < 5) {vecChaseAngOff.tilt += 2 * time_step; }
}
vec_set(cameraTPos, vecChaseOffset); // move behind and upwards
var offset;
offset = clamp(0.01 * linSpeed * linSpeed, -100, 100);
cameraTPos[0] -= offset; // offset by speed
vec_rotate(cameraTPos, vector(ang(pFocus.pan), 0, 0));
vec_add(cameraTPos, pFocus.x);
// collide with any object in the way
c_trace(pFocus.x,cameraTPos, (IGNORE_PASSABLE+IGNORE_PASSENTS+IGNORE_MODELS));
if(trace_hit == 1)
{
// offset from the target along the vector
vec_set(cameraTPos,target);
// offset from the wall along normal by the near clipping dist
vec_normalize(normal,(camera.clip_near / 2));
vec_add(cameraTPos, normal);
}
else
{
// make sure we don't clip into walls nearby
vec_diff(temp,pFocus.x, cameraTPos);
vec_normalize(temp, camera.clip_near);
vec_rotate(temp, vector(90,0,0));
vec_set(temp2, cameraTPos);
vec_add(temp2, temp); // move out by the clip_near value
c_trace(cameraTPos, temp2, (IGNORE_PASSABLE+IGNORE_PASSENTS+IGNORE_MODELS));
if(trace_hit == 1)
{
// offset from that target along the vector
vec_set(cameraTPos, target);
// offset from the wall along normal by the near clipping dist
vec_normalize(normal, (camera.clip_near / 2));
vec_add(cameraTPos,normal);
}
else
{
// rotate temp back the other dir twice as much..
vec_rotate(temp, vector(-180, 0, 0));
vec_set(temp2, cameraTPos);
vec_add(temp2, temp); // move out by the clip_near value
c_trace(cameraTPos, temp2, (IGNORE_PASSABLE+IGNORE_PASSENTS+IGNORE_MODELS));
if(trace_hit == 1)
{
// offset from that target along the vector
vec_set(cameraTPos, target);
// offset from the wall along normal by the near clipping dist
vec_normalize(normal, (camera.clip_near / 2));
vec_add(cameraTPos, normal);
}
}
}
// smooth out the transition
vec_diff(temp, cameraTPos, camera.x);
var vscale = clamp((time_step * 0.5), 0.001, 1);
vec_scale(temp, vscale);
vec_add(camera.x, temp);
// calc angle from camera to target...
vec_diff(temp, pFocus.x, cameraTPos);
vec_to_angle(cameraTAng, temp); // camera target angle looks at focus center
vec_add(cameraTAng, vecChaseAngOff.pan); // tweak it
// smooth out the rotation
vec_diff(temp, cameraTAng, camera.pan);
temp[0] = ang(temp[0]); // we only need the pan angle
vec_scale(temp, vscale);
vec_add(camera.pan, temp);