www.pudn.com > Falcon.zip > AcmiCam.cpp
#pragma optimize( "", off )
/* ------------------------------------------------------------------------
AcmiCam.cpp
ACMI Camera data and movement
Version 0.01
Written by Jim DiZoglio(x257) (c) 1997 Spectrum Holobyte
------------------------------------------------------------------------ */
#include
#include
#include
#include
#include
#include
#include
#include "Graphics\Include\grTypes.h"
#include "codelib\tools\lists\lists.h"
#include "debuggr.h"
#include "AcmiCam.h"
#define TRACKING_OFFSET 0.15F
//FILE *debugData = NULL;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
ACMICamera::ACMICamera()
{
_pos.x = 0.0F; _pos.y = 0.0F; _pos.z = 0.0F;
_rot.M11 = 1.0F; _rot.M12 = 0.0F; _rot.M13 = 0.0F;
_rot.M21 = 0.0F; _rot.M22 = 1.0F; _rot.M23 = 0.0F;
_rot.M31 = 0.0F; _rot.M32 = 0.0F; _rot.M33 = 1.0F;
_objectAz = _pannerAz = 0.0f;
_objectEl = _pannerEl = 0.0f;
// debugData = fopen("debugData.txt", "wb");
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
ACMICamera::~ACMICamera()
{
// fclose(debugData);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void ACMICamera::SetType(int type)
{
_type = type;
_objectAz = 0.0F;
_objectEl = 0.0F;
_objectRoll = 0.0F;
_localAz = 0.0F;
_localEl = 0.0F;
_objectRange = HOME_RANGE;
_rotate = 0.0F;
_azDir = 0.0F;
_elDir = 0.0F;
_slewRate = 0.1F;
_tracking = NO_TRACKING;
switch(_type)
{
case ATTACHED_CAM:
{
_rotType = OBJECT_ROTATION;
break;
}
case DETTACHED_CAM:
{
_rotType = LOCAL_ROTATION;
break;
}
}
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void ACMICamera::DoAction()
{
switch(_type)
{
case ATTACHED_CAM:
{
switch(_action)
{
case NO_ACTION:
{
SetAzDir(0.0F);
SetElDir(0.0F);
SetRotateType(OBJECT_ROTATION);
break;
}
case ZOOM_IN:
{
SetObjectRange(0.0F, ZOOM_IN);
break;
}
case ZOOM_OUT:
{
SetObjectRange(10.0F, ZOOM_OUT);
break;
}
case LOCAL_RIGHT_ROT:
{
SetRotateType(LOCAL_ROTATION);
SetAzDir(1.0F);
break;
}
case LOCAL_LEFT_ROT:
{
SetRotateType(LOCAL_ROTATION);
SetAzDir(-1.0F);
break;
}
case LOCAL_UP_ROT:
{
SetRotateType(LOCAL_ROTATION);
SetElDir(1.0F);
break;
}
case LOCAL_DOWN_ROT:
{
SetRotateType(LOCAL_ROTATION);
SetElDir(-1.0F);
break;
}
case OBJECT_RIGHT_ROT:
{
SetRotateType(OBJECT_ROTATION);
SetAzDir(-1.0F);
break;
}
case OBJECT_LEFT_ROT:
{
SetRotateType(OBJECT_ROTATION);
SetAzDir(1.0F);
break;
}
case OBJECT_UP_ROT:
{
SetRotateType(OBJECT_ROTATION);
SetElDir(1.0F);
break;
}
case OBJECT_DOWN_ROT:
{
SetRotateType(OBJECT_ROTATION);
SetElDir(-1.0F);
break;
}
case OBJECT_XRT_YUP_ROT:
{
SetRotateType(OBJECT_ROTATION);
SetAzDir(-1.0F);
SetElDir(1.0F);
break;
}
case OBJECT_XLT_YDN_ROT:
{
SetRotateType(OBJECT_ROTATION);
SetAzDir(1.0F);
SetElDir(-1.0F);
break;
}
case OBJECT_XRT_YDN_ROT:
{
SetRotateType(OBJECT_ROTATION);
SetAzDir(-1.0F);
SetElDir(-1.0F);
break;
}
case OBJECT_XLT_YUP_ROT:
{
SetRotateType(OBJECT_ROTATION);
SetAzDir(1.0F);
SetElDir(1.0F);
break;
}
case ACMI_PANNER:
{
SetRotateType(OBJECT_ROTATION);
break;
}
}
break;
}
case DETTACHED_CAM:
{
switch(_action)
{
case NO_ACTION:
{
SetAzDir(0.0F);
SetElDir(0.0F);
// SetRotateType(OBJECT_ROTATION);
break;
}
/* case ZOOM_IN:
{
// SetObjectRange(0.0F, ZOOM_IN);
SetRotateType(NO_ROTATION);
break;
}
case ZOOM_OUT:
{
// SetObjectRange(10.0F, ZOOM_OUT);
SetRotateType(NO_ROTATION);
break;
}
case LOCAL_RIGHT_ROT:
{
SetRotateType(NO_ROTATION);
// SetAzDir(1.0F);
break;
}
case LOCAL_LEFT_ROT:
{
SetRotateType(NO_ROTATION);
// SetAzDir(-1.0F);
break;
}
case LOCAL_UP_ROT:
{
SetRotateType(NO_ROTATION);
// SetElDir(1.0F);
break;
}
case LOCAL_DOWN_ROT:
{
SetRotateType(NO_ROTATION);
// SetElDir(-1.0F);
break;
} */
case OBJECT_RIGHT_ROT:
{
SetRotateType(LOCAL_ROTATION);
SetAzDir(-1.0F);
break;
}
case OBJECT_LEFT_ROT:
{
SetRotateType(LOCAL_ROTATION);
SetAzDir(1.0F);
break;
}
case OBJECT_UP_ROT:
{
SetRotateType(LOCAL_ROTATION);
SetElDir(1.0F);
break;
}
case OBJECT_DOWN_ROT:
{
SetRotateType(LOCAL_ROTATION);
SetElDir(-1.0F);
break;
}
}
break;
}
}
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void ACMICamera::UpdatePosition()
{
Trotation tilt;
DoAction();
if(_rotType == LOCAL_ROTATION)
{
_localAz += _azDir * _slewRate;
_localEl += _elDir * _slewRate;
Rotate(_objectEl + _localEl, 0.0F, _objectAz + _localAz, &_rot);
}
else
{
// Asmth and elevation angles
_objectAz += _azDir * _slewRate;
_objectEl += _elDir * _slewRate;
}
// Be around ownship, looking at it
Tilt(_objectEl, 0.0F, _objectAz, &tilt);
Translate(_objectRange * tilt.M11, _objectRange * tilt.M12, _objectRange * tilt.M13, &_pos);
if ( _tracking )
Rotate(_localEl, 0.0F, _localAz, &_rot);
else
Rotate(_objectEl, _objectRoll, _objectAz, &_rot);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void ACMICamera::UpdatePannerPosition()
{
Trotation
tilt;
Rotate(_objectEl, 0.0F, _objectAz, &_rot);
// Be around ownship, looking at it
Tilt(_objectEl, 0.0F, _objectAz, &tilt);
Translate(_objectRange * tilt.M11, _objectRange * tilt.M12, _objectRange * tilt.M13, &_pos);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void ACMICamera::Tilt(float pitch, float, float yaw, Trotation *tilt)
{
float costha, sintha, cospsi, sinpsi;
// Be around ownship, looking at it
costha = (float)cos(pitch);
sintha = (float)sin(pitch);
cospsi = (float)cos(yaw);
sinpsi = (float)sin(yaw);
tilt->M11 = cospsi * costha;
tilt->M12 = sinpsi * costha;
tilt->M13 = -sintha;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void ACMICamera::Rotate(float pitch, float roll, float yaw, Trotation* viewRotation)
{
float costha,sintha,cosphi,sinphi,cospsi,sinpsi;
costha = (float)cos(pitch);
sintha = (float)sin(pitch);
cosphi = (float)cos(roll);
sinphi = (float)sin(roll);
cospsi = (float)cos(yaw);
sinpsi = (float)sin(yaw);
viewRotation->M11 = cospsi*costha;
viewRotation->M21 = sinpsi*costha;
viewRotation->M31 = -sintha;
viewRotation->M12 = -sinpsi*cosphi + cospsi*sintha*sinphi;
viewRotation->M22 = cospsi*cosphi + sinpsi*sintha*sinphi;
viewRotation->M32 = costha*sinphi;
viewRotation->M13 = sinpsi*sinphi + cospsi*sintha*cosphi;
viewRotation->M23 = -cospsi*sinphi + sinpsi*sintha*cosphi;
viewRotation->M33 = costha*cosphi;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void ACMICamera::IncrementPannerAzEl(int currentAction, float az, float el)
{
_action = currentAction;
_objectAz = _pannerAz + az;
_objectEl = _pannerEl + el;
MonoPrint("PannA: %lf\n", _pannerAz);
MonoPrint("PannE: %lf\n", _pannerEl);
MonoPrint("ObjeA: %lf\n", _objectAz);
MonoPrint("ObjeE: %lf\n", _objectEl);
SetAzDir(0.0F);
SetElDir(0.0F);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void ACMICamera::SetObjectRange(float diff, int instruction)
{
switch(instruction)
{
case ZOOM_IN:
_objectRange = min(-50.0F, _objectRange + 50.0F);
break;
case ZOOM_OUT:
_objectRange -= diff;
break;
case HOME:
_objectRange = diff;
break;
}
SetRotateType(OBJECT_ROTATION);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void ACMICamera::TrackPoint(const Tpoint &trackingPt)
{
float
trackingAz,
trackingEl;
float
deltaX,
deltaY,
deltaZ,
deltaRange;
if(_tracking == NO_TRACKING)
return;
deltaX = trackingPt.x - (_worldPos.x + _pos.x );
deltaY = trackingPt.y - (_worldPos.y + _pos.y );
if(deltaX)
trackingAz = (float)atan2(deltaY, deltaX);
else
trackingAz = 0.0F;
deltaZ = (_worldPos.z + _pos.z ) - trackingPt.z;
#if 1
deltaRange =
(
(float)sqrt
(
deltaX * deltaX +
deltaY * deltaY +
deltaZ * deltaZ
)
);
if(deltaRange != 0.0F)
{
deltaRange = (deltaZ / deltaRange);
}
trackingEl = (float)asin(deltaRange);
#else
trackingEl = (float)atan2(sqrt(deltaX*deltaX+deltaY*deltaY), deltaZ);
#endif
/*
switch(_tracking)
{
case LOCAL_TRACKING:
{
SetLocalAz((float)trackingAz);
SetLocalEl((float)trackingEl);
break;
}
case GLOBAL_TRACKING:
{
SetObjectAz((float)trackingAz);
SetObjectEl((float)trackingEl - TRACKING_OFFSET);
break;
}
}
*/
SetLocalAz((float)trackingAz);
SetLocalEl((float)trackingEl);
// SetObjectAz((float)trackingAz);
// SetObjectEl((float)trackingEl);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void ACMICamera::UpdateChasePosition( float dT )
{
Tpoint dPos;
float dRoll;
float dist;
DoAction();
if ( dT < 0.0f )
dT = -dT;
else if ( dT > 0.0f )
dT = dT;
if(_rotType == LOCAL_ROTATION)
{
_localAz += _azDir * _slewRate;
_localEl += _elDir * _slewRate;
}
else
{
// Asmth and elevation angles
_objectAz += _azDir * _slewRate;
_objectEl += _elDir * _slewRate;
}
// Be around ownship, looking at it
// Tilt(_objectEl, 0.0F, _objectAz, &tilt);
// Translate(_objectRange * tilt.M11, _objectRange * tilt.M12, _objectRange * tilt.M13, &_pos);
/*
if ( _tracking )
Rotate(_localEl, 0.0F, _localAz, &_rot);
else
Rotate(_objectEl, _objectRoll, _objectAz, &_rot);
*/
// "spring" constants for camera roll and move
#define KMOVE 0.29f
#define KROLL 0.30f
// convert frame loop time to secs from ms
// dT = (float)frameTime * 0.001;
// get the diff between desired and current camera pos
dPos.x = _chasePos.x - _pos.x;
dPos.y = _chasePos.y - _pos.y;
dPos.z = _chasePos.z - _pos.z;
// send the camera thataway
_pos.x += dPos.x * dT * KMOVE;
_pos.y += dPos.y * dT * KMOVE;
_pos.z += dPos.z * dT * KMOVE;
// "look at" vector
dPos.x = -_pos.x;
dPos.y = -_pos.y;
dPos.z = -_pos.z;
// get new camera roll
if ( _objectRoll < -0.5f * PI && _chaseRoll > 0.5f * PI )
{
dRoll = _objectRoll + (2.0f * PI) - _chaseRoll;
}
else if ( _objectRoll > 0.5f * PI && _chaseRoll < -0.5f * PI )
{
dRoll = _objectRoll - (0.5f * PI) - _chaseRoll;
}
else // same sign
{
dRoll = _objectRoll - _chaseRoll;
}
// apply roll
_chaseRoll += dRoll * dT * KROLL;
// keep chase cam roll with +/- 180
if ( _chaseRoll > 1.0f * PI )
_chaseRoll -= 2.0f * PI;
else if ( _chaseRoll < -1.0f * PI )
_chaseRoll += 2.0f * PI;
// now get yaw and pitch based on look at vector
dist = (float)sqrt( dPos.x * dPos.x + dPos.y * dPos.y + dPos.z * dPos.z );
_objectEl = (float)-asin( dPos.z/dist );
_objectAz = (float)atan2( dPos.y, dPos.x );
Rotate(_objectEl, _chaseRoll, _objectAz, &_rot);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////