mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-10 03:40:25 +00:00
GRIM: Make an actor orient its pitch and roll too if requested. Fix #368
This commit is contained in:
parent
71b528d933
commit
3b9a59dc93
@ -459,11 +459,48 @@ void Actor::setPos(const Math::Vector3d &position) {
|
||||
}
|
||||
}
|
||||
|
||||
Math::Vector3d Actor::actorForward() const {
|
||||
if (g_grim->getGameType() == GType_GRIM) {
|
||||
return Math::Vector3d(0.f, 1.f, 0.f);
|
||||
}
|
||||
return Math::Vector3d(0.f, 0.f, 1.f);
|
||||
}
|
||||
|
||||
Math::Vector3d Actor::actorUp() const {
|
||||
if (g_grim->getGameType() == GType_GRIM) {
|
||||
return Math::Vector3d(0.f, 0.f, 1.f);
|
||||
}
|
||||
return Math::Vector3d(0.f, 1.f, 0.f);
|
||||
}
|
||||
|
||||
void Actor::turnTo(const Math::Vector3d &pos) {
|
||||
Math::Vector3d lookVector = pos - _pos;
|
||||
lookVector.normalize();
|
||||
|
||||
Math::Vector3d up = actorUp();
|
||||
if (_puckOrient) {
|
||||
Sector *s = NULL;
|
||||
g_grim->getCurrSet()->findClosestSector(_pos, &s, NULL);
|
||||
if (s) {
|
||||
up = s->getNormal();
|
||||
}
|
||||
}
|
||||
|
||||
Math::Matrix4 m;
|
||||
m.buildFromTargetDir(actorForward(), lookVector, actorUp(), up);
|
||||
|
||||
if (_puckOrient) {
|
||||
turnTo(m.getPitch(), m.getYaw(), m.getRoll());
|
||||
} else {
|
||||
turnTo(_pitch, m.getYaw(), _roll);
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::turnTo(const Math::Angle &pitchParam, const Math::Angle &yawParam, const Math::Angle &rollParam) {
|
||||
_pitch = pitchParam;
|
||||
_roll = rollParam;
|
||||
_movePitch = pitchParam;
|
||||
_moveRoll = rollParam;
|
||||
_moveYaw = yawParam;
|
||||
if (_yaw != yawParam) {
|
||||
if (_yaw != yawParam || _pitch != pitchParam || _roll != rollParam) {
|
||||
_turning = true;
|
||||
} else
|
||||
_turning = false;
|
||||
@ -1216,15 +1253,33 @@ void Actor::updateWalk() {
|
||||
}
|
||||
}
|
||||
|
||||
destPos = handleCollisionTo(_pos, destPos);
|
||||
Math::Angle y = getYawTo(destPos);
|
||||
turnTo(_pitch, y, _roll);
|
||||
turnTo(destPos);
|
||||
|
||||
dir = destPos - _pos;
|
||||
dir.normalize();
|
||||
_pos += dir * walkAmt;
|
||||
}
|
||||
|
||||
static int animTurn(float turnAmt, const Math::Angle &dest, Math::Angle *cur) {
|
||||
Math::Angle d = dest - *cur;
|
||||
d.normalize(-180);
|
||||
// If the actor won't turn because the rate is set to zero then
|
||||
// have the actor turn all the way to the destination yaw.
|
||||
// Without this some actors will lock the interface on changing
|
||||
// scenes, this affects the Bone Wagon in particular.
|
||||
if (turnAmt == 0 || turnAmt >= fabsf(d.getDegrees())) {
|
||||
*cur = dest;
|
||||
} else if (d > 0) {
|
||||
*cur += turnAmt;
|
||||
} else {
|
||||
*cur -= turnAmt;
|
||||
}
|
||||
if (d != 0) {
|
||||
return (d > 0 ? 1 : -1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Actor::update(uint frameTime) {
|
||||
// Snap actor to walkboxes if following them. This might be
|
||||
// necessary for example after activating/deactivating
|
||||
@ -1234,23 +1289,12 @@ void Actor::update(uint frameTime) {
|
||||
}
|
||||
|
||||
if (_turning) {
|
||||
float turnAmt = g_grim->getPerSecond(_turnRate) * 5.f;
|
||||
Math::Angle dyaw = _moveYaw - _yaw;
|
||||
dyaw.normalize(-180);
|
||||
// If the actor won't turn because the rate is set to zero then
|
||||
// have the actor turn all the way to the destination yaw.
|
||||
// Without this some actors will lock the interface on changing
|
||||
// scenes, this affects the Bone Wagon in particular.
|
||||
if (turnAmt == 0 || turnAmt >= fabsf(dyaw.getDegrees())) {
|
||||
setYaw(_moveYaw);
|
||||
float turnAmt = g_grim->getPerSecond(_turnRate)*5;
|
||||
_currTurnDir = animTurn(turnAmt, _moveYaw, &_yaw);
|
||||
int p = animTurn(turnAmt, _movePitch, &_pitch);
|
||||
int r = animTurn(turnAmt, _moveRoll, &_roll);
|
||||
if (_currTurnDir == 0 && p == 0 && r == 0) {
|
||||
_turning = false;
|
||||
} else if (dyaw > 0) {
|
||||
setYaw(_yaw + turnAmt);
|
||||
} else {
|
||||
setYaw(_yaw - turnAmt);
|
||||
}
|
||||
if (dyaw != 0) {
|
||||
_currTurnDir = (dyaw > 0 ? 1 : -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,6 +183,16 @@ public:
|
||||
* @see isTurning
|
||||
*/
|
||||
void turnTo(const Math::Angle &pitch, const Math::Angle &yaw, const Math::Angle &roll);
|
||||
/**
|
||||
* Turn the actor towards a point in space.
|
||||
* The effect is not immediate, the actor will slowly rotate
|
||||
* to the destination orientation.
|
||||
*
|
||||
* @param pos The position the actor should turn to.
|
||||
* @see turnTo
|
||||
* @see setRot
|
||||
*/
|
||||
void turnTo(const Math::Vector3d &pos);
|
||||
/**
|
||||
* Returns true if the actor is turning.
|
||||
*
|
||||
@ -472,6 +482,15 @@ public:
|
||||
void detach();
|
||||
Math::Quaternion getRotationQuat() const;
|
||||
|
||||
/**
|
||||
* Returns the forward direction in the local space of the actor.
|
||||
*/
|
||||
Math::Vector3d actorForward() const;
|
||||
/**
|
||||
* Returns the up direction in the local space of the actor.
|
||||
*/
|
||||
Math::Vector3d actorUp() const;
|
||||
|
||||
void setInOverworld(bool inOverworld) { _inOverworld = inOverworld; }
|
||||
bool isInOverworld() { return _inOverworld; }
|
||||
|
||||
@ -537,6 +556,8 @@ private:
|
||||
// turning animation while still allowing the actor to move in a
|
||||
// new direction immediately after reflecting off a wall.
|
||||
Math::Angle _moveYaw;
|
||||
Math::Angle _movePitch;
|
||||
Math::Angle _moveRoll;
|
||||
|
||||
// Variables for walking to a point
|
||||
bool _walking;
|
||||
|
@ -1173,20 +1173,12 @@ void Lua_V1::TurnActorTo() {
|
||||
z = lua_getnumber(zObj);
|
||||
}
|
||||
|
||||
// TODO turning stuff below is not complete
|
||||
|
||||
// Find the vector pointing from the actor to the desired location
|
||||
Math::Vector3d turnToVector(x, y, z);
|
||||
Math::Vector3d lookVector = turnToVector - actor->getPos();
|
||||
// find the angle the requested position is around the unit circle
|
||||
Math::Angle yaw = lookVector.unitCircleAngle();
|
||||
// yaw is offset from forward by 90 degrees
|
||||
yaw -= 90.0f;
|
||||
actor->turnTo(0, yaw, 0);
|
||||
actor->turnTo(turnToVector);
|
||||
|
||||
// Return true if the actor is still turning and its yaw is not the target one.
|
||||
// Return true if the actor is still turning
|
||||
// This allows manny to have the right yaw when he exits the elevator in the garage
|
||||
pushbool(actor->getYaw() != yaw);
|
||||
pushbool(actor->isTurning());
|
||||
}
|
||||
|
||||
void Lua_V1::PointActorAt() {
|
||||
|
Loading…
Reference in New Issue
Block a user