|
|
@@ -38,17 +38,17 @@ void Animation::loadInternal(const XmlElement& el)
|
|
|
ch.name = chEl.getChildElement("name").getText();
|
|
|
|
|
|
// <positionKeys>
|
|
|
- XmlElement keysEl = chEl.getChildElement("positionsKeys");
|
|
|
+ XmlElement keysEl = chEl.getChildElement("positionKeys");
|
|
|
XmlElement keyEl = keysEl.getChildElement("key");
|
|
|
do
|
|
|
{
|
|
|
Key<Vec3> key;
|
|
|
|
|
|
// <time>
|
|
|
- key.time = keyEl.getFloat();
|
|
|
+ key.time = keyEl.getChildElement("time").getFloat();
|
|
|
|
|
|
// <value>
|
|
|
- key.value = keyEl.getVec3();
|
|
|
+ key.value = keyEl.getChildElement("value").getVec3();
|
|
|
|
|
|
// push_back
|
|
|
ch.positions.push_back(key);
|
|
|
@@ -65,10 +65,15 @@ void Animation::loadInternal(const XmlElement& el)
|
|
|
Key<Quat> key;
|
|
|
|
|
|
// <time>
|
|
|
- key.time = keyEl.getFloat();
|
|
|
+ key.time = keyEl.getChildElement("time").getFloat();
|
|
|
|
|
|
// <value>
|
|
|
- key.value = Quat(keyEl.getVec4());
|
|
|
+ Quat a = Quat(keyEl.getChildElement("value").getVec4());
|
|
|
+ key.value.x() = a.w();
|
|
|
+ key.value.y() = a.x();
|
|
|
+ key.value.z() = a.y();
|
|
|
+ key.value.w() = a.z();
|
|
|
+ // XXX
|
|
|
|
|
|
// push_back
|
|
|
ch.rotations.push_back(key);
|
|
|
@@ -87,10 +92,10 @@ void Animation::loadInternal(const XmlElement& el)
|
|
|
Key<F32> key;
|
|
|
|
|
|
// <time>
|
|
|
- key.time = keyEl.getFloat();
|
|
|
+ key.time = keyEl.getChildElement("time").getFloat();
|
|
|
|
|
|
// <value>
|
|
|
- key.value = keyEl.getFloat();
|
|
|
+ key.value = keyEl.getChildElement("value").getFloat();
|
|
|
|
|
|
// push_back
|
|
|
ch.scales.push_back(key);
|
|
|
@@ -105,4 +110,46 @@ void Animation::loadInternal(const XmlElement& el)
|
|
|
} while(chEl);
|
|
|
}
|
|
|
|
|
|
+//==============================================================================
|
|
|
+void Animation::interpolate(U channelIndex, F32 time,
|
|
|
+ Vec3& pos, Quat& rot, F32& scale) const
|
|
|
+{
|
|
|
+ ANKI_ASSERT(time >= startTime && time <= startTime + duration);
|
|
|
+ ANKI_ASSERT(channelIndex < channels.size());
|
|
|
+
|
|
|
+ const AnimationChannel& channel = channels[channelIndex];
|
|
|
+
|
|
|
+ // Position
|
|
|
+ if(channel.positions.size() > 1)
|
|
|
+ {
|
|
|
+ auto next = channel.positions.begin();
|
|
|
+
|
|
|
+ do
|
|
|
+ {
|
|
|
+ } while((next->time < time) && (++next != channel.positions.end()));
|
|
|
+
|
|
|
+ ANKI_ASSERT(next != channel.positions.end());
|
|
|
+ auto prev = next - 1;
|
|
|
+
|
|
|
+ F32 u = (time - prev->time) / (next->time - prev->time);
|
|
|
+ pos = linearInterpolate(prev->value, next->value, u);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Rotation
|
|
|
+ if(channel.rotations.size() > 1)
|
|
|
+ {
|
|
|
+ auto next = channel.rotations.begin();
|
|
|
+
|
|
|
+ do
|
|
|
+ {
|
|
|
+ } while((next->time < time) && (++next != channel.rotations.end()));
|
|
|
+
|
|
|
+ ANKI_ASSERT(next != channel.rotations.end());
|
|
|
+ auto prev = next - 1;
|
|
|
+
|
|
|
+ F32 u = (time - prev->time) / (next->time - prev->time);
|
|
|
+ rot = prev->value.slerp(next->value, u);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
} // end namespace anki
|