Skip to content

Commit

Permalink
Refactor camera radar jump to remove OBJ_TARGET
Browse files Browse the repository at this point in the history
  • Loading branch information
thiagorb authored and KJeff01 committed Oct 1, 2020
1 parent 4f63575 commit 1a4b35e
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 156 deletions.
3 changes: 1 addition & 2 deletions src/basedef.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ enum OBJECT_TYPE
OBJ_STRUCTURE, ///< All Buildings
OBJ_FEATURE, ///< Things like roads, trees, bridges, fires
OBJ_PROJECTILE, ///< Comes out of guns, stupid :-)
OBJ_TARGET, ///< for the camera tracking
OBJ_NUM_TYPES, ///< number of object types - MUST BE LAST
};

Expand Down Expand Up @@ -176,7 +175,7 @@ static inline int objPosDiffSq(SIMPLE_OBJECT const *pos1, SIMPLE_OBJECT const *p
return objPosDiffSq(pos1->pos, pos2->pos);
}

// True iff object is a droid, structure or feature (not a projectile). Will incorrectly return true if passed a nonsense object of type OBJ_TARGET or OBJ_NUM_TYPES.
// True iff object is a droid, structure or feature (not a projectile). Will incorrectly return true if passed a nonsense object of type OBJ_NUM_TYPES.
static inline bool isBaseObject(SIMPLE_OBJECT const *psObject)
{
return psObject != nullptr && psObject->type != OBJ_PROJECTILE;
Expand Down
1 change: 0 additions & 1 deletion src/baseobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,6 @@ void checkObject(const SIMPLE_OBJECT *psObject, const char *const location_descr
break;

case OBJ_FEATURE:
case OBJ_TARGET:
break;

default:
Expand Down
3 changes: 0 additions & 3 deletions src/objects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,6 @@ const char *objInfo(const BASE_OBJECT *psObj)
case OBJ_PROJECTILE:
sstrcpy(info, "Projectile"); // TODO
break;
case OBJ_TARGET:
sstrcpy(info, "Target"); // TODO
break;
default:
sstrcpy(info, "Unknown object type");
break;
Expand Down
4 changes: 0 additions & 4 deletions src/projectile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1567,10 +1567,6 @@ static int32_t objectDamageDispatch(DAMAGE *psDamage)
ASSERT(!"invalid object type: bullet", "invalid object type: OBJ_PROJECTILE (id=%d)", psDamage->psDest->id);
break;

case OBJ_TARGET:
ASSERT(!"invalid object type: target", "invalid object type: OBJ_TARGET (id=%d)", psDamage->psDest->id);
break;

default:
ASSERT(!"unknown object type", "unknown object type %d, id=%d", psDamage->psDest->type, psDamage->psDest->id);
}
Expand Down
1 change: 0 additions & 1 deletion src/qtscriptdebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,6 @@ static const char *getObjType(const BASE_OBJECT *psObj)
case OBJ_STRUCTURE: return "Structure";
case OBJ_FEATURE: return "Feature";
case OBJ_PROJECTILE: return "Projectile";
case OBJ_TARGET: return "Target";
default: break;
}
return "Unknown";
Expand Down
1 change: 0 additions & 1 deletion src/qtscriptfuncs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,6 @@ static void updateLabelModel()
case SCRIPT_PLAYER:
case SCRIPT_RESEARCH:
case OBJ_PROJECTILE:
case OBJ_TARGET:
case SCRIPT_COUNT: c = "ERROR"; break;
}
labelModel->setItem(nextRow, 1, new QStandardItem(QString(c)));
Expand Down
208 changes: 69 additions & 139 deletions src/warcam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,14 @@ static SDWORD warCamLogoRotation;

/* Used to animate radar jump */
struct RADAR_JUMP {
Animation<Vector3f> animation;
/* This object is used ONLY to check the "type" of tracking. Ideally the logic should be changed so that we don't need it */
BASE_OBJECT target;
Animation<Vector3f> position;
Animation<Vector3f> rotation;
};

static RADAR_JUMP radarJump
static RADAR_JUMP radarJumpAnimation
{
Animation<Vector3f>(&graphicsTime, EASE_IN_OUT),
{OBJ_TARGET, 0, 0}
Animation<Vector3f>(&graphicsTime, EASE_IN_OUT)
};

static SDWORD presAvAngle = 0;
Expand All @@ -114,14 +113,9 @@ static SDWORD presAvAngle = 0;
/* How much info do you want when tracking a droid - this toggles full stat info */
static bool bFullInfo = false;

/* Are we requesting a new track to start that is a radar (location) track? */
static bool bRadarTrackingRequested = false;

/* World coordinates for a radar track/jump */
static float radarX, radarY;

// Prototypes
static bool camTrackCamera();
static void camRadarJump();

//-----------------------------------------------------------------------------------
/* Sets the camera to inactive to begin with */
Expand All @@ -134,23 +128,6 @@ void initWarCam()
warCamLogoRotation = 0;
}


/* Static function that switches off tracking - and might not be desirable? - Jim?*/
static void camSwitchOff()
{
/* Restore the angles */
// player.r.x = trackingCamera.oldView.r.x;
player.r.z = trackingCamera.oldView.r.z;

/* And height */
/* Is this desirable??? */
// player.p.y = trackingCamera.oldView.p.y;

/* Restore distance */
setViewDistance(trackingCamera.oldDistance);
}


#define LEADER_LEFT 1
#define LEADER_RIGHT 2
#define LEADER_UP 3
Expand Down Expand Up @@ -296,57 +273,21 @@ static void processLeaderSelection()
}
}


/* Sets up the dummy target for the camera */
static void setUpRadarTarget(SDWORD x, SDWORD y)
{
auto initial = Vector3f(player.p);
auto target = Vector3f(x, calculateCameraHeightAt(map_coord(x), map_coord(y)), y);
radarJump.animation.start(initial, target);
radarJump.animation.setDuration(glm::log(glm::length(target - initial)) * 100);
radarJump.target.rot.direction = calcDirection(player.p.x, player.p.z, x, y);
radarJump.target.rot.pitch = 0;
radarJump.target.rot.roll = 0;
}


/* Attempts to find the target for the camera to track */
static BASE_OBJECT *camFindTarget()
{
/* See if we can find a selected droid. If there's more than one
droid selected for the present player, then we track the oldest
one. */

if (bRadarTrackingRequested)
{
setUpRadarTarget(radarX, radarY);
bRadarTrackingRequested = false;
return (&radarJump.target);
}

return camFindDroidTarget();
}


/* Updates the camera position/angle along with the object movement */
bool processWarCam()
void processWarCam()
{
BASE_OBJECT *foundTarget;
bool Status = true;

/* Get out if the camera isn't active */
if (trackingCamera.status == CAM_INACTIVE)
{
return (true);
}

/* Ensure that the camera only ever flips state within this routine! */
switch (trackingCamera.status)
{
case CAM_INACTIVE:
break;

case CAM_REQUEST:

/* See if we can find the target to follow */
foundTarget = camFindTarget();
foundTarget = camFindDroidTarget();

if (foundTarget && !foundTarget->died)
{
Expand Down Expand Up @@ -378,7 +319,7 @@ bool processWarCam()
Camera track came back false, either because droid died or is
no longer selected, so reset to old values
*/
foundTarget = camFindTarget();
foundTarget = camFindDroidTarget();
if (foundTarget && !foundTarget->died)
{
trackingCamera.status = CAM_REQUEST;
Expand All @@ -392,25 +333,16 @@ bool processWarCam()
processLeaderSelection();

break;

case CAM_RADAR_JUMP:
camRadarJump();
break;

case CAM_RESET:
/* Reset camera to pre-droid tracking status */
if ((trackingCamera.target == nullptr)
|| (trackingCamera.target->type != OBJ_TARGET))
{
camSwitchOff();
}
/* Switch to inactive mode */
trackingCamera.status = CAM_INACTIVE;
Status = false;
break;
case CAM_INACTIVE:
case CAM_TRACK_OBJECT:
case CAM_TRACK_LOCATION:
ASSERT(false, "Unexpected status for tracking camera");
break;
}

return Status;
}

//-----------------------------------------------------------------------------------
Expand All @@ -427,14 +359,7 @@ void setWarCamActive(bool status)
/* We're tracking a droid */
if (trackingCamera.status != CAM_INACTIVE)
{
if (bRadarTrackingRequested)
{
trackingCamera.status = CAM_REQUEST;
}
else
{
return;
}
return;
}
else
{
Expand Down Expand Up @@ -906,30 +831,22 @@ static bool camTrackCamera()
return (false);
}

updateCameraAcceleration(CAM_ALL);
updateCameraVelocity(CAM_ALL);
updateCameraPosition(CAM_ALL);

/* Update the acceleration,velocity and rotation of the camera for rotation */
/* You can track roll as well (z axis) but it makes you ill and looks
like a flight sim, so for now just pitch and orientation */


if (trackingCamera.target->type == OBJ_DROID)
{
updateCameraAcceleration(CAM_ALL);
updateCameraVelocity(CAM_ALL);
updateCameraPosition(CAM_ALL);

psDroid = (DROID *)trackingCamera.target;
psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION];
if (psPropStats->propulsionType == PROPULSION_TYPE_LIFT)
{
bFlying = true;
}
} else {
radarJump.animation.update();
trackingCamera.position = radarJump.animation.getCurrent();
}

if (trackingCamera.target->type == OBJ_DROID)
{
if (bFlying)
{
updateCameraRotationAcceleration(CAM_ALL);
Expand Down Expand Up @@ -980,20 +897,23 @@ static bool camTrackCamera()
}
}

/* Switch off if we're jumping to a new location and we've got there */
if (getRadarTrackingStatus())
return (true);
}

/* Updates the viewpoint animation to jump to the location pointed at the radar */
static void camRadarJump()
{
radarJumpAnimation.position.update();
radarJumpAnimation.rotation.update();
player.p = radarJumpAnimation.position.getCurrent();
player.r = radarJumpAnimation.rotation.getCurrent();

if (radarJumpAnimation.position.isFinished() && radarJumpAnimation.rotation.isFinished())
{
/* This will ensure we come to a rest and terminate the tracking
routine once we're close enough
*/
auto rotationFactor = glm::dot(trackingCamera.rotVel, trackingCamera.rotVel) + glm::dot(trackingCamera.rotAccel, trackingCamera.rotAccel);
if (radarJump.animation.isFinished() && rotationFactor < 1.f)
{
setWarCamActive(false);
}
trackingCamera.status = CAM_INACTIVE;
}
return (true);
}

//-----------------------------------------------------------------------------------
DROID *getTrackingDroid()
{
Expand Down Expand Up @@ -1069,37 +989,47 @@ void camToggleInfo()
bFullInfo = !bFullInfo;
}

/**
* Find the angle equivalent to `from` in the interval between `to - 180°` and to `to + 180°`.
*
* For example:
* - if `from` is `10°` and `to` is `350°`, it will return `370°`.
* - if `from` is `350°` and `to` is `0°`, it will return `-10°`.
*
* Useful while animating a rotation, to always animate the shortest angle delta.
*/
int32_t calculateRelativeAngle(uint16_t from, uint16_t to)
{
return to + (int16_t)(from - to);
}

/* Informs the tracking camera that we want to start tracking to a new radar target */
void requestRadarTrack(SDWORD x, SDWORD y)
void requestRadarTrack(SDWORD x, SDWORD y)
{
radarX = (SWORD)x;
radarY = (SWORD)y;
bRadarTrackingRequested = true;
trackingCamera.status = CAM_REQUEST;
processWarCam();
auto initialPosition = Vector3f(player.p);
auto targetPosition = Vector3f(x, calculateCameraHeightAt(map_coord(x), map_coord(y)), y);
auto animationDuration = glm::log(glm::length(targetPosition - initialPosition)) * 100;

auto targetRotationTemp = trackingCamera.status == CAM_TRACKING ? trackingCamera.oldView.r : player.r;
auto targetRotation = Vector3i((uint16_t)targetRotationTemp.x, (uint16_t)targetRotationTemp.y, (uint16_t)0);

auto initialRotation = Vector3f(
calculateRelativeAngle(player.r.x, targetRotation.x),
calculateRelativeAngle(player.r.y, targetRotation.y),
calculateRelativeAngle(player.r.z, targetRotation.z)
);

radarJumpAnimation.position.start(initialPosition, targetPosition);
radarJumpAnimation.rotation.start(initialRotation, targetRotation);
radarJumpAnimation.position.setDuration(animationDuration);
radarJumpAnimation.rotation.setDuration(animationDuration);
trackingCamera.status = CAM_RADAR_JUMP;
}

/* Returns whether we're presently tracking to a new _location_ */
bool getRadarTrackingStatus()
{
bool retVal;

if (trackingCamera.status == CAM_INACTIVE)
{
retVal = false;
}
else
{
if (trackingCamera.target && trackingCamera.target->type == OBJ_TARGET)
{
retVal = true;
}
else
{
retVal = false;
}
}
return (retVal);
return trackingCamera.status == CAM_RADAR_JUMP;
}

void camInformOfRotation(Vector3i *rotation)
Expand Down
Loading

0 comments on commit 1a4b35e

Please sign in to comment.