Clean up position height methods + add new. Now we have the ability to losslessly read and write positions to entities from the scripts.
This was SVN commit r15230.
This commit is contained in:
parent
c3a0ac43bf
commit
5ae9f678b0
@ -72,8 +72,9 @@ public:
|
||||
// m_LastX/Z contain the position from the start of the most recent turn
|
||||
// m_PrevX/Z conatain the position from the turn before that
|
||||
entity_pos_t m_X, m_Z, m_LastX, m_LastZ, m_PrevX, m_PrevZ; // these values contain undefined junk if !InWorld
|
||||
entity_pos_t m_YOffset, m_LastYOffset;
|
||||
bool m_RelativeToGround; // whether m_YOffset is relative to terrain/water plane, or an absolute height
|
||||
|
||||
entity_pos_t m_Y, m_LastYDifference; // either the relative or the absolute Y coordinate
|
||||
bool m_RelativeToGround; // whether m_Y is relative to terrain/water plane, or an absolute height
|
||||
|
||||
entity_angle_t m_RotX, m_RotY, m_RotZ;
|
||||
|
||||
@ -128,7 +129,8 @@ public:
|
||||
|
||||
m_InWorld = false;
|
||||
|
||||
m_LastYOffset = m_YOffset = paramNode.GetChild("Altitude").ToFixed();
|
||||
m_LastYDifference = entity_pos_t::Zero();
|
||||
m_Y = paramNode.GetChild("Altitude").ToFixed();
|
||||
m_RelativeToGround = true;
|
||||
m_Floating = paramNode.GetChild("Floating").ToBool();
|
||||
|
||||
@ -152,16 +154,19 @@ public:
|
||||
if (m_InWorld)
|
||||
{
|
||||
serialize.NumberFixed_Unbounded("x", m_X);
|
||||
serialize.NumberFixed_Unbounded("y", m_Y);
|
||||
serialize.NumberFixed_Unbounded("z", m_Z);
|
||||
serialize.NumberFixed_Unbounded("last x", m_LastX);
|
||||
serialize.NumberFixed_Unbounded("last y diff", m_LastYDifference);
|
||||
serialize.NumberFixed_Unbounded("last z", m_LastZ);
|
||||
}
|
||||
serialize.NumberI32_Unbounded("territory", m_Territory);
|
||||
serialize.NumberFixed_Unbounded("rot x", m_RotX);
|
||||
serialize.NumberFixed_Unbounded("rot y", m_RotY);
|
||||
serialize.NumberFixed_Unbounded("rot z", m_RotZ);
|
||||
serialize.NumberFixed_Unbounded("altitude", m_YOffset);
|
||||
serialize.NumberFixed_Unbounded("altitude", m_Y);
|
||||
serialize.Bool("relative", m_RelativeToGround);
|
||||
serialize.Bool("floating", m_Floating);
|
||||
|
||||
if (serialize.IsDebug())
|
||||
{
|
||||
@ -186,7 +191,6 @@ public:
|
||||
break;
|
||||
}
|
||||
serialize.StringASCII("anchor", anchor, 0, 16);
|
||||
serialize.Bool("floating", m_Floating);
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,20 +202,22 @@ public:
|
||||
if (m_InWorld)
|
||||
{
|
||||
deserialize.NumberFixed_Unbounded("x", m_X);
|
||||
deserialize.NumberFixed_Unbounded("y", m_Y);
|
||||
deserialize.NumberFixed_Unbounded("z", m_Z);
|
||||
deserialize.NumberFixed_Unbounded("last x", m_LastX);
|
||||
deserialize.NumberFixed_Unbounded("last y diff", m_LastYDifference);
|
||||
deserialize.NumberFixed_Unbounded("last z", m_LastZ);
|
||||
}
|
||||
deserialize.NumberI32_Unbounded("territory", m_Territory);
|
||||
deserialize.NumberFixed_Unbounded("rot x", m_RotX);
|
||||
deserialize.NumberFixed_Unbounded("rot y", m_RotY);
|
||||
deserialize.NumberFixed_Unbounded("rot z", m_RotZ);
|
||||
deserialize.NumberFixed_Unbounded("altitude", m_YOffset);
|
||||
deserialize.NumberFixed_Unbounded("altitude", m_Y);
|
||||
deserialize.Bool("relative", m_RelativeToGround);
|
||||
deserialize.Bool("floating", m_Floating);
|
||||
// TODO: should there be range checks on all these values?
|
||||
|
||||
m_InterpolatedRotY = m_RotY.ToFloat();
|
||||
m_LastYOffset = m_YOffset;
|
||||
|
||||
if (m_InWorld)
|
||||
UpdateXZRotation();
|
||||
@ -239,7 +245,7 @@ public:
|
||||
m_InWorld = true;
|
||||
m_LastX = m_PrevX = m_X;
|
||||
m_LastZ = m_PrevZ = m_Z;
|
||||
m_LastYOffset = m_YOffset;
|
||||
m_LastYDifference = entity_pos_t::Zero();
|
||||
}
|
||||
|
||||
AdvertisePositionChanges();
|
||||
@ -256,7 +262,7 @@ public:
|
||||
m_InWorld = true;
|
||||
m_LastX = m_PrevX = m_X;
|
||||
m_LastZ = m_PrevZ = m_Z;
|
||||
m_LastYOffset = m_YOffset;
|
||||
m_LastYDifference = entity_pos_t::Zero();
|
||||
}
|
||||
|
||||
AdvertisePositionChanges();
|
||||
@ -278,37 +284,69 @@ public:
|
||||
|
||||
virtual void SetHeightOffset(entity_pos_t dy)
|
||||
{
|
||||
if (m_RelativeToGround)
|
||||
{
|
||||
m_LastYOffset = m_YOffset;
|
||||
m_YOffset = dy;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_LastYOffset = m_YOffset = dy;
|
||||
m_RelativeToGround = true;
|
||||
}
|
||||
|
||||
// subtract the offset and replace with a new offset
|
||||
m_LastYDifference = dy - GetHeightOffset();
|
||||
m_Y += m_LastYDifference;
|
||||
AdvertisePositionChanges();
|
||||
}
|
||||
|
||||
virtual entity_pos_t GetHeightOffset()
|
||||
{
|
||||
return m_YOffset;
|
||||
if (m_RelativeToGround)
|
||||
return m_Y;
|
||||
// not relative to the ground, so the height offset is m_Y - ground height
|
||||
entity_pos_t baseY;
|
||||
CmpPtr<ICmpTerrain> cmpTerrain(GetSystemEntity());
|
||||
if (cmpTerrain)
|
||||
baseY = cmpTerrain->GetGroundLevel(m_X, m_Z);
|
||||
|
||||
if (m_Floating)
|
||||
{
|
||||
CmpPtr<ICmpWaterManager> cmpWaterManager(GetSystemEntity());
|
||||
if (cmpWaterManager)
|
||||
baseY = std::max(baseY, cmpWaterManager->GetWaterLevel(m_X, m_Z));
|
||||
}
|
||||
return m_Y - baseY;
|
||||
}
|
||||
|
||||
virtual void SetHeightFixed(entity_pos_t y)
|
||||
{
|
||||
if (m_RelativeToGround)
|
||||
// subtract the absolute height and replace it with a new absolute height
|
||||
m_LastYDifference = y - GetHeightFixed();
|
||||
m_Y += m_LastYDifference;
|
||||
AdvertisePositionChanges();
|
||||
}
|
||||
|
||||
virtual entity_pos_t GetHeightFixed()
|
||||
{
|
||||
if (!m_RelativeToGround)
|
||||
return m_Y;
|
||||
// relative to the ground, so the fixed height = ground height + m_Y
|
||||
entity_pos_t baseY;
|
||||
CmpPtr<ICmpTerrain> cmpTerrain(GetSystemEntity());
|
||||
if (cmpTerrain)
|
||||
baseY = cmpTerrain->GetGroundLevel(m_X, m_Z);
|
||||
|
||||
if (m_Floating)
|
||||
{
|
||||
m_LastYOffset = m_YOffset = y;
|
||||
m_RelativeToGround = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_LastYOffset = m_YOffset;
|
||||
m_YOffset = y;
|
||||
CmpPtr<ICmpWaterManager> cmpWaterManager(GetSystemEntity());
|
||||
if (cmpWaterManager)
|
||||
baseY = std::max(baseY, cmpWaterManager->GetWaterLevel(m_X, m_Z));
|
||||
}
|
||||
return m_Y + baseY;
|
||||
}
|
||||
|
||||
virtual bool IsHeightRelative()
|
||||
{
|
||||
return m_RelativeToGround;
|
||||
}
|
||||
|
||||
virtual void SetHeightRelative(bool relative)
|
||||
{
|
||||
// move y to use the right offset (from terrain or from map origin)
|
||||
m_Y = relative ? GetHeightOffset() : GetHeightFixed();
|
||||
m_RelativeToGround = relative;
|
||||
m_LastYDifference = entity_pos_t::Zero();
|
||||
}
|
||||
|
||||
virtual bool IsFloating()
|
||||
@ -316,6 +354,11 @@ public:
|
||||
return m_Floating;
|
||||
}
|
||||
|
||||
virtual void SetFloating(bool flag)
|
||||
{
|
||||
m_Floating = flag;
|
||||
}
|
||||
|
||||
virtual CFixedVector3D GetPosition()
|
||||
{
|
||||
if (!m_InWorld)
|
||||
@ -324,22 +367,7 @@ public:
|
||||
return CFixedVector3D();
|
||||
}
|
||||
|
||||
entity_pos_t baseY;
|
||||
if (m_RelativeToGround)
|
||||
{
|
||||
CmpPtr<ICmpTerrain> cmpTerrain(GetSystemEntity());
|
||||
if (cmpTerrain)
|
||||
baseY = cmpTerrain->GetGroundLevel(m_X, m_Z);
|
||||
|
||||
if (m_Floating)
|
||||
{
|
||||
CmpPtr<ICmpWaterManager> cmpWaterManager(GetSystemEntity());
|
||||
if (cmpWaterManager)
|
||||
baseY = std::max(baseY, cmpWaterManager->GetWaterLevel(m_X, m_Z));
|
||||
}
|
||||
}
|
||||
|
||||
return CFixedVector3D(m_X, baseY + m_YOffset, m_Z);
|
||||
return CFixedVector3D(m_X, GetHeightFixed(), m_Z);
|
||||
}
|
||||
|
||||
virtual CFixedVector2D GetPosition2D()
|
||||
@ -361,22 +389,7 @@ public:
|
||||
return CFixedVector3D();
|
||||
}
|
||||
|
||||
entity_pos_t baseY;
|
||||
if (m_RelativeToGround)
|
||||
{
|
||||
CmpPtr<ICmpTerrain> cmpTerrain(GetSystemEntity());
|
||||
if (cmpTerrain)
|
||||
baseY = cmpTerrain->GetGroundLevel(m_PrevX, m_PrevZ);
|
||||
|
||||
if (m_Floating)
|
||||
{
|
||||
CmpPtr<ICmpWaterManager> cmpWaterMan(GetSystemEntity());
|
||||
if (cmpWaterMan)
|
||||
baseY = std::max(baseY, cmpWaterMan->GetWaterLevel(m_PrevX, m_PrevZ));
|
||||
}
|
||||
}
|
||||
|
||||
return CFixedVector3D(m_PrevX, baseY + m_YOffset, m_PrevZ);
|
||||
return CFixedVector3D(m_PrevX, GetHeightFixed(), m_PrevZ);
|
||||
}
|
||||
|
||||
virtual CFixedVector2D GetPreviousPosition2D()
|
||||
@ -472,23 +485,22 @@ public:
|
||||
float x, z, rotY;
|
||||
GetInterpolatedPosition2D(frameOffset, x, z, rotY);
|
||||
|
||||
float baseY = 0;
|
||||
if (m_RelativeToGround)
|
||||
{
|
||||
CmpPtr<ICmpTerrain> cmpTerrain(GetSystemEntity());
|
||||
if (cmpTerrain)
|
||||
baseY = cmpTerrain->GetExactGroundLevel(x, z);
|
||||
float y = GetHeightFixed().ToFloat() + Interpolate(0.f, m_LastYDifference.ToFloat(), frameOffset);
|
||||
|
||||
if (m_Floating || forceFloating)
|
||||
if (forceFloating)
|
||||
{
|
||||
// if the actor has a <float/> flag, it shouldn't be serialized,
|
||||
// so it's handled here separately
|
||||
CmpPtr<ICmpTerrain> cmpTerrain(GetSystemEntity());
|
||||
CmpPtr<ICmpWaterManager> cmpWaterManager(GetSystemEntity());
|
||||
if (cmpTerrain && cmpWaterManager)
|
||||
{
|
||||
CmpPtr<ICmpWaterManager> cmpWaterManager(GetSystemEntity());
|
||||
if (cmpWaterManager)
|
||||
baseY = std::max(baseY, cmpWaterManager->GetExactWaterLevel(x, z));
|
||||
float diff = (cmpWaterManager->GetWaterLevel(m_X, m_Z) - cmpTerrain->GetGroundLevel(m_X, m_Z)).ToFloat();
|
||||
if (diff > 0.f)
|
||||
y += diff;
|
||||
}
|
||||
}
|
||||
|
||||
float y = baseY + Interpolate(m_LastYOffset.ToFloat(), m_YOffset.ToFloat(), frameOffset);
|
||||
|
||||
CMatrix3D m;
|
||||
|
||||
// linear interpolation is good enough (for RotX/Z).
|
||||
@ -560,7 +572,7 @@ public:
|
||||
|
||||
m_LastX = m_X;
|
||||
m_LastZ = m_Z;
|
||||
m_LastYOffset = m_YOffset;
|
||||
m_LastYDifference = entity_pos_t::Zero();
|
||||
|
||||
|
||||
// warn when a position change also causes a territory change under the entity
|
||||
|
@ -30,7 +30,11 @@ DEFINE_INTERFACE_METHOD_2("JumpTo", void, ICmpPosition, JumpTo, entity_pos_t, en
|
||||
DEFINE_INTERFACE_METHOD_1("SetHeightOffset", void, ICmpPosition, SetHeightOffset, entity_pos_t)
|
||||
DEFINE_INTERFACE_METHOD_0("GetHeightOffset", entity_pos_t, ICmpPosition, GetHeightOffset)
|
||||
DEFINE_INTERFACE_METHOD_1("SetHeightFixed", void, ICmpPosition, SetHeightFixed, entity_pos_t)
|
||||
DEFINE_INTERFACE_METHOD_0("GetHeightFixed", entity_pos_t, ICmpPosition, GetHeightFixed)
|
||||
DEFINE_INTERFACE_METHOD_0("IsHeightRelative", bool, ICmpPosition, IsHeightRelative)
|
||||
DEFINE_INTERFACE_METHOD_1("SetHeightRelative", void, ICmpPosition, SetHeightRelative, bool)
|
||||
DEFINE_INTERFACE_METHOD_0("IsFloating", bool, ICmpPosition, IsFloating)
|
||||
DEFINE_INTERFACE_METHOD_1("SetFloating", void, ICmpPosition, SetFloating, bool)
|
||||
DEFINE_INTERFACE_METHOD_0("GetPosition", CFixedVector3D, ICmpPosition, GetPosition)
|
||||
DEFINE_INTERFACE_METHOD_0("GetPosition2D", CFixedVector2D, ICmpPosition, GetPosition2D)
|
||||
DEFINE_INTERFACE_METHOD_0("GetPreviousPosition", CFixedVector3D, ICmpPosition, GetPreviousPosition)
|
||||
|
@ -94,16 +94,36 @@ public:
|
||||
virtual entity_pos_t GetHeightOffset() = 0;
|
||||
|
||||
/**
|
||||
* Set the vertical position as a fixed, absolute value.
|
||||
* Will stay at this height until the next call to SetHeightFixed or SetHeightOffset.
|
||||
* Set the vertical position above the map zero point
|
||||
*/
|
||||
virtual void SetHeightFixed(entity_pos_t y) = 0;
|
||||
|
||||
/**
|
||||
* Returns the vertical offset above the map zero point
|
||||
*/
|
||||
virtual entity_pos_t GetHeightFixed() = 0;
|
||||
|
||||
/**
|
||||
* Returns true iff the entity will follow the terrain height (possibly with an offset)
|
||||
*/
|
||||
virtual bool IsHeightRelative() = 0;
|
||||
|
||||
/**
|
||||
* When set to true, the entity will follow the terrain height (possibly with an offset)
|
||||
* When set to false, it's height won't change automatically
|
||||
*/
|
||||
virtual void SetHeightRelative(bool flag) = 0;
|
||||
|
||||
/**
|
||||
* Returns whether the entity floats on water.
|
||||
*/
|
||||
virtual bool IsFloating() = 0;
|
||||
|
||||
/**
|
||||
* Set the entity to float on water
|
||||
*/
|
||||
virtual void SetFloating(bool flag) = 0;
|
||||
|
||||
/**
|
||||
* Returns the current x,y,z position (no interpolation).
|
||||
* Depends on the current terrain heightmap.
|
||||
|
@ -48,7 +48,11 @@ public:
|
||||
virtual void SetHeightOffset(entity_pos_t UNUSED(dy)) { }
|
||||
virtual entity_pos_t GetHeightOffset() { return entity_pos_t::Zero(); }
|
||||
virtual void SetHeightFixed(entity_pos_t UNUSED(y)) { }
|
||||
virtual entity_pos_t GetHeightFixed() { return entity_pos_t::Zero(); }
|
||||
virtual bool IsHeightRelative() { return true; }
|
||||
virtual void SetHeightRelative(bool UNUSED(relative)) { }
|
||||
virtual bool IsFloating() { return false; }
|
||||
virtual void SetFloating(bool UNUSED(flag)) { }
|
||||
virtual CFixedVector3D GetPosition() { return CFixedVector3D(); }
|
||||
virtual CFixedVector2D GetPosition2D() { return CFixedVector2D(); }
|
||||
virtual CFixedVector3D GetPreviousPosition() { return CFixedVector3D(); }
|
||||
|
Loading…
Reference in New Issue
Block a user