mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-21 01:05:59 +00:00
EMI: Implement head limits.
This commit is contained in:
parent
3adbd1fdcf
commit
23a99a9f2b
@ -1360,6 +1360,13 @@ void Actor::setHead(const char *joint, const Math::Vector3d &offset) {
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::setHeadLimits(float yawRange, float maxPitch, float minPitch) {
|
||||
if (!_costumeStack.empty()) {
|
||||
EMICostume *costume = static_cast<EMICostume *>(_costumeStack.back());
|
||||
costume->setHeadLimits(yawRange, maxPitch, minPitch);
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::setLookAtRate(float rate) {
|
||||
_costumeStack.back()->setLookAtRate(rate);
|
||||
}
|
||||
|
@ -505,6 +505,7 @@ public:
|
||||
float getLookAtRate() const;
|
||||
void setHead(int joint1, int joint2, int joint3, float maxRoll, float maxPitch, float maxYaw);
|
||||
void setHead(const char *joint, const Math::Vector3d &offset);
|
||||
void setHeadLimits(float yawRange, float maxPitch, float minPitch);
|
||||
|
||||
void setCollisionMode(CollisionMode mode);
|
||||
void setCollisionScale(float scale);
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
namespace Grim {
|
||||
|
||||
EMIHead::EMIHead(EMICostume *costume) {
|
||||
EMIHead::EMIHead(EMICostume *costume) : _yawRange(80.0f), _minPitch(-30.0f), _maxPitch(30.0f) {
|
||||
_cost = costume;
|
||||
}
|
||||
|
||||
@ -36,6 +36,12 @@ void EMIHead::setJoint(const char *joint, const Math::Vector3d &offset) {
|
||||
_offset = offset;
|
||||
}
|
||||
|
||||
void EMIHead::setLimits(float yawRange, float maxPitch, float minPitch) {
|
||||
_yawRange = yawRange;
|
||||
_maxPitch = maxPitch;
|
||||
_minPitch = minPitch;
|
||||
}
|
||||
|
||||
void EMIHead::lookAt(bool entering, const Math::Vector3d &point, float rate, const Math::Matrix4 &matrix) {
|
||||
if (!_cost->_emiSkel || !_cost->_emiSkel->_obj)
|
||||
return;
|
||||
@ -77,6 +83,16 @@ void EMIHead::lookAt(bool entering, const Math::Vector3d &point, float rate, con
|
||||
// Convert from world-space to joint-space.
|
||||
lookAtTM = worldToJoint * lookAtTM;
|
||||
|
||||
// Apply angle limits.
|
||||
Math::Angle p, y, r;
|
||||
lookAtTM.getXYZ(&y, &p, &r, Math::EO_ZXY);
|
||||
|
||||
y.clampDegrees(_yawRange);
|
||||
p.clampDegrees(_minPitch, _maxPitch);
|
||||
r.clampDegrees(30.0f);
|
||||
|
||||
lookAtTM.buildFromXYZ(y, p, r, Math::EO_ZXY);
|
||||
|
||||
lookAtQuat.fromMatrix(lookAtTM.getRotation());
|
||||
}
|
||||
|
||||
@ -108,6 +124,9 @@ void EMIHead::saveState(SaveGame *state) const {
|
||||
state->writeFloat(_headRot.y());
|
||||
state->writeFloat(_headRot.z());
|
||||
state->writeFloat(_headRot.w());
|
||||
state->writeFloat(_yawRange);
|
||||
state->writeFloat(_minPitch);
|
||||
state->writeFloat(_maxPitch);
|
||||
}
|
||||
|
||||
void EMIHead::restoreState(SaveGame *state) {
|
||||
@ -118,6 +137,11 @@ void EMIHead::restoreState(SaveGame *state) {
|
||||
_headRot.y() = state->readFloat();
|
||||
_headRot.z() = state->readFloat();
|
||||
_headRot.w() = state->readFloat();
|
||||
if (state->saveMinorVersion() >= 16) {
|
||||
_yawRange = state->readFloat();
|
||||
_minPitch = state->readFloat();
|
||||
_maxPitch = state->readFloat();
|
||||
}
|
||||
} else {
|
||||
state->readLESint32();
|
||||
state->readLESint32();
|
||||
|
@ -36,6 +36,7 @@ public:
|
||||
EMIHead(EMICostume *costume);
|
||||
|
||||
void setJoint(const char *joint, const Math::Vector3d &offset);
|
||||
void setLimits(float yawRange, float maxPitch, float minPitch);
|
||||
void lookAt(bool entering, const Math::Vector3d &point, float rate, const Math::Matrix4 &matrix) override;
|
||||
void loadJoints(ModelNode *nodes) override {}
|
||||
void saveState(SaveGame *state) const override;
|
||||
@ -46,6 +47,9 @@ private:
|
||||
Common::String _jointName;
|
||||
Math::Vector3d _offset;
|
||||
Math::Quaternion _headRot;
|
||||
float _yawRange;
|
||||
float _maxPitch;
|
||||
float _minPitch;
|
||||
};
|
||||
|
||||
} // end of namespace Grim
|
||||
|
@ -314,4 +314,8 @@ void EMICostume::setHead(const char *joint, const Math::Vector3d &offset) {
|
||||
static_cast<EMIHead *>(_head)->setJoint(joint, offset);
|
||||
}
|
||||
|
||||
void EMICostume::setHeadLimits(float yawRange, float maxPitch, float minPitch) {
|
||||
static_cast<EMIHead *>(_head)->setLimits(yawRange, maxPitch, minPitch);
|
||||
}
|
||||
|
||||
} // end of namespace Grim
|
||||
|
@ -57,6 +57,7 @@ public:
|
||||
|
||||
void setWearChoreActive(bool isActive);
|
||||
void setHead(const char *joint, const Math::Vector3d &offset);
|
||||
void setHeadLimits(float yawRange, float maxPitch, float minPitch);
|
||||
public:
|
||||
EMIChore *_wearChore;
|
||||
EMISkelComponent *_emiSkel;
|
||||
|
@ -843,9 +843,9 @@ void Lua_V2::GetActorPuckVector() {
|
||||
|
||||
void Lua_V2::SetActorHeadLimits() {
|
||||
lua_Object actorObj = lua_getparam(1);
|
||||
lua_Object param2Obj = lua_getparam(2);
|
||||
lua_Object param3Obj = lua_getparam(3);
|
||||
lua_Object param4Obj = lua_getparam(4);
|
||||
lua_Object yawObj = lua_getparam(2);
|
||||
lua_Object maxPitchObj = lua_getparam(3);
|
||||
lua_Object minPitchObj = lua_getparam(4);
|
||||
|
||||
if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R'))
|
||||
return;
|
||||
@ -854,13 +854,11 @@ void Lua_V2::SetActorHeadLimits() {
|
||||
if (!actor)
|
||||
return;
|
||||
|
||||
if (lua_isnumber(param2Obj) && lua_isnumber(param3Obj) && lua_isnumber(param4Obj)) {
|
||||
float param2 = lua_getnumber(param2Obj); // belows needs multiply by some runtime value
|
||||
float param3 = lua_getnumber(param3Obj);
|
||||
float param4 = lua_getnumber(param4Obj);
|
||||
// FIXME: implement missing func
|
||||
//actor->func(param2, param3, param4);
|
||||
warning("Lua_V2::SetActorHeadLimits: implement opcode. actor: %s, params: %f, %f, %f", actor->getName().c_str(), param2, param3, param4);
|
||||
if (lua_isnumber(yawObj) && lua_isnumber(minPitchObj) && lua_isnumber(maxPitchObj)) {
|
||||
float yaw = lua_getnumber(yawObj);
|
||||
float maxPitch = lua_getnumber(maxPitchObj);
|
||||
float minPitch = lua_getnumber(minPitchObj);
|
||||
actor->setHeadLimits(yaw / 2, maxPitch, -minPitch);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ namespace Grim {
|
||||
#define SAVEGAME_FOOTERTAG 'ESAV'
|
||||
|
||||
uint SaveGame::SAVEGAME_MAJOR_VERSION = 22;
|
||||
uint SaveGame::SAVEGAME_MINOR_VERSION = 15;
|
||||
uint SaveGame::SAVEGAME_MINOR_VERSION = 16;
|
||||
|
||||
SaveGame *SaveGame::openForLoading(const Common::String &filename) {
|
||||
Common::InSaveFile *inSaveFile = g_system->getSavefileManager()->openForLoading(filename);
|
||||
|
@ -52,6 +52,16 @@ Angle &Angle::clampDegrees(float mag) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
Angle &Angle::clampDegrees(float min, float max) {
|
||||
_degrees = getDegrees(-180.f);
|
||||
if (_degrees >= max)
|
||||
setDegrees(max);
|
||||
if (_degrees <= min)
|
||||
setDegrees(min);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Angle::setDegrees(float degrees) {
|
||||
_degrees = degrees;
|
||||
}
|
||||
|
@ -60,6 +60,14 @@ public:
|
||||
*/
|
||||
Angle &clampDegrees(float mag);
|
||||
|
||||
/**
|
||||
* Clamp the angle to range [-min, max]
|
||||
*
|
||||
* \param min The lower bound of the range, in degrees.
|
||||
* \param max The upper bound of the range, in degrees.
|
||||
*/
|
||||
Angle &clampDegrees(float min, float max);
|
||||
|
||||
void setDegrees(float degrees);
|
||||
void setRadians(float radians);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user