Template abuse to clean up llkeyframemotion. Only functional change: std::map<F32, curve> to std::vector<std::pair<F32, curve>>. Sorry in advance Linux.
This commit is contained in:
@@ -138,257 +138,6 @@ U32 LLKeyframeMotion::JointMotionList::dumpDiagInfo(bool silent) const
|
||||
return total_size;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// ****Curve classes
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ScaleCurve::ScaleCurve()
|
||||
//-----------------------------------------------------------------------------
|
||||
LLKeyframeMotion::ScaleCurve::ScaleCurve()
|
||||
{
|
||||
mInterpolationType = LLKeyframeMotion::IT_LINEAR;
|
||||
mNumKeys = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ScaleCurve::~ScaleCurve()
|
||||
//-----------------------------------------------------------------------------
|
||||
LLKeyframeMotion::ScaleCurve::~ScaleCurve()
|
||||
{
|
||||
mKeys.clear();
|
||||
mNumKeys = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// getValue()
|
||||
//-----------------------------------------------------------------------------
|
||||
LLVector3 LLKeyframeMotion::ScaleCurve::getValue(F32 time, F32 duration)
|
||||
{
|
||||
LLVector3 value;
|
||||
|
||||
if (mKeys.empty())
|
||||
{
|
||||
value.clearVec();
|
||||
return value;
|
||||
}
|
||||
|
||||
key_map_t::iterator right = mKeys.lower_bound(time);
|
||||
if (right == mKeys.end())
|
||||
{
|
||||
// Past last key
|
||||
--right;
|
||||
value = right->second.mScale;
|
||||
}
|
||||
else if (right == mKeys.begin() || right->first == time)
|
||||
{
|
||||
// Before first key or exactly on a key
|
||||
value = right->second.mScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Between two keys
|
||||
key_map_t::iterator left = right; --left;
|
||||
F32 index_before = left->first;
|
||||
F32 index_after = right->first;
|
||||
ScaleKey& scale_before = left->second;
|
||||
ScaleKey& scale_after = right->second;
|
||||
if (right == mKeys.end())
|
||||
{
|
||||
scale_after = mLoopInKey;
|
||||
index_after = duration;
|
||||
}
|
||||
|
||||
F32 u = (time - index_before) / (index_after - index_before);
|
||||
value = interp(u, scale_before, scale_after);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// interp()
|
||||
//-----------------------------------------------------------------------------
|
||||
LLVector3 LLKeyframeMotion::ScaleCurve::interp(F32 u, ScaleKey& before, ScaleKey& after)
|
||||
{
|
||||
switch (mInterpolationType)
|
||||
{
|
||||
case IT_STEP:
|
||||
return before.mScale;
|
||||
|
||||
default:
|
||||
case IT_LINEAR:
|
||||
case IT_SPLINE:
|
||||
return lerp(before.mScale, after.mScale, u);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RotationCurve::RotationCurve()
|
||||
//-----------------------------------------------------------------------------
|
||||
LLKeyframeMotion::RotationCurve::RotationCurve()
|
||||
{
|
||||
mInterpolationType = LLKeyframeMotion::IT_LINEAR;
|
||||
mNumKeys = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RotationCurve::~RotationCurve()
|
||||
//-----------------------------------------------------------------------------
|
||||
LLKeyframeMotion::RotationCurve::~RotationCurve()
|
||||
{
|
||||
mKeys.clear();
|
||||
mNumKeys = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RotationCurve::getValue()
|
||||
//-----------------------------------------------------------------------------
|
||||
LLQuaternion LLKeyframeMotion::RotationCurve::getValue(F32 time, F32 duration)
|
||||
{
|
||||
LLQuaternion value;
|
||||
|
||||
if (mKeys.empty())
|
||||
{
|
||||
value = LLQuaternion::DEFAULT;
|
||||
return value;
|
||||
}
|
||||
|
||||
key_map_t::iterator right = mKeys.lower_bound(time);
|
||||
if (right == mKeys.end())
|
||||
{
|
||||
// Past last key
|
||||
--right;
|
||||
value = right->second.mRotation;
|
||||
}
|
||||
else if (right == mKeys.begin() || right->first == time)
|
||||
{
|
||||
// Before first key or exactly on a key
|
||||
value = right->second.mRotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Between two keys
|
||||
key_map_t::iterator left = right; --left;
|
||||
F32 index_before = left->first;
|
||||
F32 index_after = right->first;
|
||||
RotationKey& rot_before = left->second;
|
||||
RotationKey& rot_after = right->second;
|
||||
if (right == mKeys.end())
|
||||
{
|
||||
rot_after = mLoopInKey;
|
||||
index_after = duration;
|
||||
}
|
||||
|
||||
F32 u = (time - index_before) / (index_after - index_before);
|
||||
value = interp(u, rot_before, rot_after);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// interp()
|
||||
//-----------------------------------------------------------------------------
|
||||
LLQuaternion LLKeyframeMotion::RotationCurve::interp(F32 u, RotationKey& before, RotationKey& after)
|
||||
{
|
||||
switch (mInterpolationType)
|
||||
{
|
||||
case IT_STEP:
|
||||
return before.mRotation;
|
||||
|
||||
default:
|
||||
case IT_LINEAR:
|
||||
case IT_SPLINE:
|
||||
return nlerp(u, before.mRotation, after.mRotation);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// PositionCurve::PositionCurve()
|
||||
//-----------------------------------------------------------------------------
|
||||
LLKeyframeMotion::PositionCurve::PositionCurve()
|
||||
{
|
||||
mInterpolationType = LLKeyframeMotion::IT_LINEAR;
|
||||
mNumKeys = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// PositionCurve::~PositionCurve()
|
||||
//-----------------------------------------------------------------------------
|
||||
LLKeyframeMotion::PositionCurve::~PositionCurve()
|
||||
{
|
||||
mKeys.clear();
|
||||
mNumKeys = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// PositionCurve::getValue()
|
||||
//-----------------------------------------------------------------------------
|
||||
LLVector3 LLKeyframeMotion::PositionCurve::getValue(F32 time, F32 duration)
|
||||
{
|
||||
LLVector3 value;
|
||||
|
||||
if (mKeys.empty())
|
||||
{
|
||||
value.clearVec();
|
||||
return value;
|
||||
}
|
||||
|
||||
key_map_t::iterator right = mKeys.lower_bound(time);
|
||||
if (right == mKeys.end())
|
||||
{
|
||||
// Past last key
|
||||
--right;
|
||||
value = right->second.mPosition;
|
||||
}
|
||||
else if (right == mKeys.begin() || right->first == time)
|
||||
{
|
||||
// Before first key or exactly on a key
|
||||
value = right->second.mPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Between two keys
|
||||
key_map_t::iterator left = right; --left;
|
||||
F32 index_before = left->first;
|
||||
F32 index_after = right->first;
|
||||
PositionKey& pos_before = left->second;
|
||||
PositionKey& pos_after = right->second;
|
||||
if (right == mKeys.end())
|
||||
{
|
||||
pos_after = mLoopInKey;
|
||||
index_after = duration;
|
||||
}
|
||||
|
||||
F32 u = (time - index_before) / (index_after - index_before);
|
||||
value = interp(u, pos_before, pos_after);
|
||||
}
|
||||
|
||||
llassert(value.isFinite());
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// interp()
|
||||
//-----------------------------------------------------------------------------
|
||||
LLVector3 LLKeyframeMotion::PositionCurve::interp(F32 u, PositionKey& before, PositionKey& after)
|
||||
{
|
||||
switch (mInterpolationType)
|
||||
{
|
||||
case IT_STEP:
|
||||
return before.mPosition;
|
||||
default:
|
||||
case IT_LINEAR:
|
||||
case IT_SPLINE:
|
||||
return lerp(before.mPosition, after.mPosition, u);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// JointMotion class
|
||||
@@ -1668,7 +1417,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id)
|
||||
success = dp.unpackVector3(rot_angles, "rot_angles") && rot_angles.isFinite();
|
||||
|
||||
LLQuaternion::Order ro = StringToOrder("ZYX");
|
||||
rot_key.mRotation = mayaQ(rot_angles.mV[VX], rot_angles.mV[VY], rot_angles.mV[VZ], ro);
|
||||
rot_key.mValue = mayaQ(rot_angles.mV[VX], rot_angles.mV[VY], rot_angles.mV[VZ], ro);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1680,10 +1429,10 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id)
|
||||
rot_vec.mV[VX] = U16_to_F32(x, -1.f, 1.f);
|
||||
rot_vec.mV[VY] = U16_to_F32(y, -1.f, 1.f);
|
||||
rot_vec.mV[VZ] = U16_to_F32(z, -1.f, 1.f);
|
||||
rot_key.mRotation.unpackFromVector3(rot_vec);
|
||||
rot_key.mValue.unpackFromVector3(rot_vec);
|
||||
}
|
||||
|
||||
if( !(rot_key.mRotation.isFinite()) )
|
||||
if( !(rot_key.mValue.isFinite()) )
|
||||
{
|
||||
LL_WARNS() << "non-finite angle in rotation key"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
@@ -1697,9 +1446,11 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rCurve->mKeys[time] = rot_key;
|
||||
rCurve->mKeys.emplace_back(time, rot_key);
|
||||
}
|
||||
|
||||
std::sort(rCurve->mKeys.begin(), rCurve->mKeys.end(), [](const auto& a, const auto& b) { return a.first < b.first; });
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// scan position curve header
|
||||
//---------------------------------------------------------------------
|
||||
@@ -1752,12 +1503,12 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id)
|
||||
|
||||
if (old_version)
|
||||
{
|
||||
success = dp.unpackVector3(pos_key.mPosition, "pos");
|
||||
success = dp.unpackVector3(pos_key.mValue, "pos");
|
||||
|
||||
//MAINT-6162
|
||||
pos_key.mPosition.mV[VX] = llclamp( pos_key.mPosition.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
|
||||
pos_key.mPosition.mV[VY] = llclamp( pos_key.mPosition.mV[VY], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
|
||||
pos_key.mPosition.mV[VZ] = llclamp( pos_key.mPosition.mV[VZ], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
|
||||
pos_key.mValue.mV[VX] = llclamp( pos_key.mValue.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
|
||||
pos_key.mValue.mV[VY] = llclamp( pos_key.mValue.mV[VY], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
|
||||
pos_key.mValue.mV[VZ] = llclamp( pos_key.mValue.mV[VZ], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
|
||||
|
||||
}
|
||||
else
|
||||
@@ -1768,12 +1519,12 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id)
|
||||
success &= dp.unpackU16(y, "pos_y");
|
||||
success &= dp.unpackU16(z, "pos_z");
|
||||
|
||||
pos_key.mPosition.mV[VX] = U16_to_F32(x, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
|
||||
pos_key.mPosition.mV[VY] = U16_to_F32(y, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
|
||||
pos_key.mPosition.mV[VZ] = U16_to_F32(z, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
|
||||
pos_key.mValue.mV[VX] = U16_to_F32(x, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
|
||||
pos_key.mValue.mV[VY] = U16_to_F32(y, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
|
||||
pos_key.mValue.mV[VZ] = U16_to_F32(z, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
|
||||
}
|
||||
|
||||
if( !(pos_key.mPosition.isFinite()) )
|
||||
if( !(pos_key.mValue.isFinite()) )
|
||||
{
|
||||
LL_WARNS() << "non-finite position in key"
|
||||
<< " for animation " << asset_id << LL_ENDL;
|
||||
@@ -1787,14 +1538,17 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pCurve->mKeys[pos_key.mTime] = pos_key;
|
||||
pCurve->mKeys.emplace_back(pos_key.mTime, pos_key);
|
||||
|
||||
if (is_pelvis)
|
||||
{
|
||||
mJointMotionList->mPelvisBBox.addPoint(pos_key.mPosition);
|
||||
mJointMotionList->mPelvisBBox.addPoint(pos_key.mValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::sort(pCurve->mKeys.begin(), pCurve->mKeys.end(), [](const auto& a, const auto& b) { return a.first < b.first; });
|
||||
|
||||
joint_motion->mUsage = joint_state->getUsage();
|
||||
}
|
||||
|
||||
@@ -2087,7 +1841,7 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const
|
||||
U16 time_short = F32_to_U16(rot_key.mTime, 0.f, mJointMotionList->mDuration);
|
||||
success &= dp.packU16(time_short, "time");
|
||||
|
||||
LLVector3 rot_angles = rot_key.mRotation.packToVector3();
|
||||
LLVector3 rot_angles = rot_key.mValue.packToVector3();
|
||||
|
||||
U16 x, y, z;
|
||||
rot_angles.quantize16(-1.f, 1.f, -1.f, 1.f);
|
||||
@@ -2110,15 +1864,15 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const
|
||||
success &= dp.packU16(time_short, "time");
|
||||
|
||||
U16 x, y, z;
|
||||
pos_key.mPosition.quantize16(-LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
|
||||
x = F32_to_U16(pos_key.mPosition.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
|
||||
y = F32_to_U16(pos_key.mPosition.mV[VY], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
|
||||
z = F32_to_U16(pos_key.mPosition.mV[VZ], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
|
||||
pos_key.mValue.quantize16(-LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
|
||||
x = F32_to_U16(pos_key.mValue.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
|
||||
y = F32_to_U16(pos_key.mValue.mV[VY], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
|
||||
z = F32_to_U16(pos_key.mValue.mV[VZ], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET);
|
||||
success &= dp.packU16(x, "pos_x");
|
||||
success &= dp.packU16(y, "pos_y");
|
||||
success &= dp.packU16(z, "pos_z");
|
||||
|
||||
LL_DEBUGS("BVH") << " pos: t " << pos_key.mTime << " pos " << pos_key.mPosition.mV[VX] <<","<< pos_key.mPosition.mV[VY] <<","<< pos_key.mPosition.mV[VZ] << LL_ENDL;
|
||||
LL_DEBUGS("BVH") << " pos: t " << pos_key.mTime << " pos " << pos_key.mValue.mV[VX] <<","<< pos_key.mValue.mV[VY] <<","<< pos_key.mValue.mV[VZ] << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2296,9 +2050,9 @@ void LLKeyframeMotion::setLoopIn(F32 in_point)
|
||||
rot_curve->mLoopInKey.mTime = mJointMotionList->mLoopInPoint;
|
||||
scale_curve->mLoopInKey.mTime = mJointMotionList->mLoopInPoint;
|
||||
|
||||
pos_curve->mLoopInKey.mPosition = pos_curve->getValue(mJointMotionList->mLoopInPoint, mJointMotionList->mDuration);
|
||||
rot_curve->mLoopInKey.mRotation = rot_curve->getValue(mJointMotionList->mLoopInPoint, mJointMotionList->mDuration);
|
||||
scale_curve->mLoopInKey.mScale = scale_curve->getValue(mJointMotionList->mLoopInPoint, mJointMotionList->mDuration);
|
||||
pos_curve->mLoopInKey.mValue = pos_curve->getValue(mJointMotionList->mLoopInPoint, mJointMotionList->mDuration);
|
||||
rot_curve->mLoopInKey.mValue = rot_curve->getValue(mJointMotionList->mLoopInPoint, mJointMotionList->mDuration);
|
||||
scale_curve->mLoopInKey.mValue = scale_curve->getValue(mJointMotionList->mLoopInPoint, mJointMotionList->mDuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2325,9 +2079,9 @@ void LLKeyframeMotion::setLoopOut(F32 out_point)
|
||||
rot_curve->mLoopOutKey.mTime = mJointMotionList->mLoopOutPoint;
|
||||
scale_curve->mLoopOutKey.mTime = mJointMotionList->mLoopOutPoint;
|
||||
|
||||
pos_curve->mLoopOutKey.mPosition = pos_curve->getValue(mJointMotionList->mLoopOutPoint, mJointMotionList->mDuration);
|
||||
rot_curve->mLoopOutKey.mRotation = rot_curve->getValue(mJointMotionList->mLoopOutPoint, mJointMotionList->mDuration);
|
||||
scale_curve->mLoopOutKey.mScale = scale_curve->getValue(mJointMotionList->mLoopOutPoint, mJointMotionList->mDuration);
|
||||
pos_curve->mLoopOutKey.mValue = pos_curve->getValue(mJointMotionList->mLoopOutPoint, mJointMotionList->mDuration);
|
||||
rot_curve->mLoopOutKey.mValue = rot_curve->getValue(mJointMotionList->mLoopOutPoint, mJointMotionList->mDuration);
|
||||
scale_curve->mLoopOutKey.mValue = scale_curve->getValue(mJointMotionList->mLoopOutPoint, mJointMotionList->mDuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -387,101 +387,99 @@ public:
|
||||
|
||||
enum InterpolationType { IT_STEP, IT_LINEAR, IT_SPLINE };
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// ScaleKey
|
||||
//-------------------------------------------------------------------------
|
||||
class ScaleKey
|
||||
{
|
||||
public:
|
||||
ScaleKey() { mTime = 0.0f; }
|
||||
ScaleKey(F32 time, const LLVector3 &scale) { mTime = time; mScale = scale; }
|
||||
|
||||
F32 mTime;
|
||||
LLVector3 mScale;
|
||||
template<typename T>
|
||||
struct lerp_op {
|
||||
static T lerp(F32 t, const T& before, const T& after)
|
||||
{
|
||||
return ::lerp(before, after, t);
|
||||
}
|
||||
};
|
||||
template<>
|
||||
struct lerp_op<LLQuaternion> {
|
||||
static LLQuaternion lerp(F32 t, const LLQuaternion& before, const LLQuaternion& after)
|
||||
{
|
||||
return ::nlerp(t, before, after);
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// RotationKey
|
||||
//-------------------------------------------------------------------------
|
||||
class RotationKey
|
||||
template<typename T>
|
||||
struct Curve
|
||||
{
|
||||
public:
|
||||
RotationKey() { mTime = 0.0f; }
|
||||
RotationKey(F32 time, const LLQuaternion &rotation) { mTime = time; mRotation = rotation; }
|
||||
struct Key
|
||||
{
|
||||
Key() = default;
|
||||
Key(F32 time, const T& value) { mTime = time; mValue = value; }
|
||||
F32 mTime = 0;
|
||||
T mValue;
|
||||
};
|
||||
|
||||
F32 mTime;
|
||||
LLQuaternion mRotation;
|
||||
};
|
||||
T interp(F32 u, Key& before, Key& after)
|
||||
{
|
||||
switch (mInterpolationType)
|
||||
{
|
||||
case IT_STEP:
|
||||
return before.mValue;
|
||||
default:
|
||||
case IT_LINEAR:
|
||||
case IT_SPLINE:
|
||||
return lerp_op<T>::lerp(u, before.mValue, after.mValue);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// PositionKey
|
||||
//-------------------------------------------------------------------------
|
||||
class PositionKey
|
||||
{
|
||||
public:
|
||||
PositionKey() { mTime = 0.0f; }
|
||||
PositionKey(F32 time, const LLVector3 &position) { mTime = time; mPosition = position; }
|
||||
T getValue(F32 time, F32 duration)
|
||||
{
|
||||
if (mKeys.empty())
|
||||
{
|
||||
return T();
|
||||
}
|
||||
|
||||
F32 mTime;
|
||||
LLVector3 mPosition;
|
||||
};
|
||||
T value;
|
||||
key_map_t::iterator right = std::lower_bound(mKeys.begin(), mKeys.end(), time, [](const auto& a, const auto& b) { return a.first < b; });
|
||||
if (right == mKeys.end())
|
||||
{
|
||||
// Past last key
|
||||
--right;
|
||||
value = right->second.mValue;
|
||||
}
|
||||
else if (right == mKeys.begin() || right->first == time)
|
||||
{
|
||||
// Before first key or exactly on a key
|
||||
value = right->second.mValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Between two keys
|
||||
key_map_t::iterator left = right; --left;
|
||||
F32 index_before = left->first;
|
||||
F32 index_after = right->first;
|
||||
Key& pos_before = left->second;
|
||||
Key& pos_after = right->second;
|
||||
if (right == mKeys.end())
|
||||
{
|
||||
pos_after = mLoopInKey;
|
||||
index_after = duration;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// ScaleCurve
|
||||
//-------------------------------------------------------------------------
|
||||
class ScaleCurve
|
||||
{
|
||||
public:
|
||||
ScaleCurve();
|
||||
~ScaleCurve();
|
||||
LLVector3 getValue(F32 time, F32 duration);
|
||||
LLVector3 interp(F32 u, ScaleKey& before, ScaleKey& after);
|
||||
F32 u = (time - index_before) / (index_after - index_before);
|
||||
value = interp(u, pos_before, pos_after);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
InterpolationType mInterpolationType;
|
||||
S32 mNumKeys;
|
||||
typedef std::map<F32, ScaleKey> key_map_t;
|
||||
InterpolationType mInterpolationType = LLKeyframeMotion::IT_LINEAR;
|
||||
S32 mNumKeys = 0;
|
||||
typedef std::vector< std::pair<F32, Key> > key_map_t;
|
||||
key_map_t mKeys;
|
||||
ScaleKey mLoopInKey;
|
||||
ScaleKey mLoopOutKey;
|
||||
Key mLoopInKey;
|
||||
Key mLoopOutKey;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// RotationCurve
|
||||
//-------------------------------------------------------------------------
|
||||
class RotationCurve
|
||||
{
|
||||
public:
|
||||
RotationCurve();
|
||||
~RotationCurve();
|
||||
LLQuaternion getValue(F32 time, F32 duration);
|
||||
LLQuaternion interp(F32 u, RotationKey& before, RotationKey& after);
|
||||
|
||||
InterpolationType mInterpolationType;
|
||||
S32 mNumKeys;
|
||||
typedef std::map<F32, RotationKey> key_map_t;
|
||||
key_map_t mKeys;
|
||||
RotationKey mLoopInKey;
|
||||
RotationKey mLoopOutKey;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// PositionCurve
|
||||
//-------------------------------------------------------------------------
|
||||
class PositionCurve
|
||||
{
|
||||
public:
|
||||
PositionCurve();
|
||||
~PositionCurve();
|
||||
LLVector3 getValue(F32 time, F32 duration);
|
||||
LLVector3 interp(F32 u, PositionKey& before, PositionKey& after);
|
||||
|
||||
InterpolationType mInterpolationType;
|
||||
S32 mNumKeys;
|
||||
typedef std::map<F32, PositionKey> key_map_t;
|
||||
key_map_t mKeys;
|
||||
PositionKey mLoopInKey;
|
||||
PositionKey mLoopOutKey;
|
||||
};
|
||||
typedef Curve<LLVector3> ScaleCurve;
|
||||
typedef ScaleCurve::Key ScaleKey;
|
||||
typedef Curve<LLQuaternion> RotationCurve;
|
||||
typedef RotationCurve::Key RotationKey;
|
||||
typedef Curve<LLVector3> PositionCurve;
|
||||
typedef PositionCurve::Key PositionKey;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// JointMotion
|
||||
|
||||
Reference in New Issue
Block a user