Camera follow target issue
by Daniel Allessi · in Torque Game Engine · 11/04/2006 (9:35 am) · 1 replies
I have written a camera system where each camera is placed in a stationary position in the level, and can optionally pan or tilt (or both) to follow the player. This lets me have Resident Evil style cameras or allow them to pan around and cover both sides of a hallway or even tilt to watch the player going up and down stairs. The current camera is decided when the player passes through a trigger to set the active camera.
The problem is that tilt is coming out skewed. I have spent a lot of time already looking over everything and I cannot figure out where the problem might be. Hopefully someone can shed some light on the issue.
Here is the function in question (which is updated every $levelCameras::updateDelay from a master camera update function):
The problem is that tilt is coming out skewed. I have spent a lot of time already looking over everything and I cannot figure out where the problem might be. Hopefully someone can shed some light on the issue.
Here is the function in question (which is updated every $levelCameras::updateDelay from a master camera update function):
function Camera::updateTracking(%this)
{
if(%this.getDatablock().className !$= "levelCamera")
return;
// calculate direction vector
%dirVec = vectorSub(%this.trackObject.getPosition(), %this.getPosition());
// pan ------------------
%oldAngZ = getWord(%this.getTransform(), 5) * getWord(%this.getTransform(), 6);
if(%this.canPan)
{
%rotAngZ = mAtan(getWord(%dirVec, 0), getWord(%dirVec, 1));
%deltaZ = (%rotAngZ - %oldAngZ);
// take the shortest pan
if(%deltaZ > mDegToRad(180))
%deltaZ -= mDegToRad(360);
else if(%deltaZ < mDegToRad(-180))
%deltaZ += mDegToRad(360);
// if change required is too small, skip it
if(mAbs(%deltaZ) >= $levelCameras::minFollowChange)
{
// smooth out the rotation - we don't want to 'snap' instantly to the new orientation
%rotAngZ = %oldAngZ + (%deltaZ / $levelCameras::followSmoothing);
}
else
%deltaZ = 0;
}
else
{
%rotAngZ = %oldAngZ;
}
// tilt -----------------
%oldAngXY = getWord(%this.getTransform(), 3) * getWord(%this.getTransform(), 6);
if(%this.canTilt)
{
%targetAngXY = mAtan(vectorLen(%dirVec), getWord(%dirVec, 2)) - ($PI / 2);
%deltaXY = (%targetAngXY - %oldAngXY);
// if change required is too small, skip it
if(mAbs(%deltaXY) >= $levelCameras::minFollowChange)
{
%rotAngXY = %oldAngXY + (%deltaXY / $levelCameras::followSmoothing);
}
else
%deltaXY = 0;
}
else
{
%rotAngXY = %oldAngXY;
}
echo("Orig Trans:" SPC %this.getTransform());
// combine rotations ----
%matZ = matrixCreateFromEuler("0 0" SPC -%rotAngZ);
%matXY = matrixCreateFromEuler(-%rotAngXY SPC "0 0");
%finalRot = getWords(matrixMultiply(%matZ, %matXY), 3, 6);
%this.setTransform(%this.getPosition() SPC %finalRot);
echo("oldAngZ:" SPC %oldAngZ);
echo("oldAngXY:" SPC %oldAngXY);
echo("targetAngZ:" SPC %targetAngZ);
echo("targetAngXY:" SPC %targetAngXY);
echo("RotAngZ:" SPC %rotAngZ);
echo("RotAngXY:" SPC %rotAngXY);
echo("DeltaZ:" SPC %deltaZ);
echo("DeltaXY:" SPC %deltaXY);
echo("FinalRot:" SPC %finalRot);
echo("New Trans:" SPC %this.getTransform());
}
Torque Owner Daniel Allessi
on a camera that pans and tilts the output after the camera has 'settled' into what it considers a locked position are:
but it's aiming higher than the player and DeltaZ should be 0 if it's 'locked' (DeltaZ is perfect 0 when tilting is disabled) Given settings of:
the output is:
and the camera seems to lock on ok but the output tells me it's still not working properly.
Finally, for comparison, here is the output of the same camera with tilt disabled using the same settings:
The camera is aiming far too high, but as you can see, pan is now perfect as it should be. Thanks to anyone who read this far, and hopefully someone better at math can shed some light on why this is occuring.