KeyframeAnimPtr ResourceLoader::getKeyframe(const char *fname) { for (Common::List<KeyframeAnim *>::const_iterator i = _keyframeAnims.begin(); i != _keyframeAnims.end(); ++i) { KeyframeAnim *k = *i; if (strcmp(fname, k->filename()) == 0) { return k; } } return loadKeyframe(fname); }
KeyframeAnimPtr ResourceLoader::getKeyframe(const Common::String &fname) { Common::String filename = fname; filename.toLowercase(); for (Common::List<KeyframeAnim *>::const_iterator i = _keyframeAnims.begin(); i != _keyframeAnims.end(); ++i) { KeyframeAnim *k = *i; if (filename == k->getFilename()) { return k; } } return loadKeyframe(fname); }
// Load a blend shape animation track Track BlendShape::loadTrack(float start,float stop,float rate,ParamList& params,int targetIndex,int startPoseId) { MStatus stat; MString msg; std::vector<float> times; // Create a track for current clip Track t; t.m_type = TT_POSE; t.m_target = m_target; t.m_index = targetIndex; t.m_vertexKeyframes.clear(); // Calculate times from clip sample rate times.clear(); if (rate <= 0) { std::cout << "invalid sample rate for the clip (must be >0), we skip it\n"; std::cout.flush(); return t; } for (float time=start; time<stop; time+=rate) times.push_back(time); times.push_back(stop); // Get animation length float length=0; if (times.size() >= 0) length = times[times.size()-1] - times[0]; if (length < 0) { std::cout << "invalid time range for the clip, we skip it\n"; std::cout.flush(); return t; } // Evaluate animation curves at selected times for (int i=0; i<times.size(); i++) { // Set time to wanted sample time MAnimControl::setCurrentTime(MTime(times[i],MTime::kSeconds)); // Load a keyframe at current time vertexKeyframe key = loadKeyframe(times[i]-times[0],params,targetIndex, startPoseId); // Add keyframe to joint track if (key.poserefs.size() > 0) t.addVertexKeyframe(key); } // Clip successfully loaded return t; }
// Load an animation clip MStatus skeleton::loadClip(MString clipName,int start,int stop,int rate) { uint fps = getFps(); float frameTime = 1000.0f / fps; MStatus stat; int i,j; std::vector<int> times; if (m_joints.size() < 0) return MS::kFailure; times.clear(); for (int t=start; t<stop; t+=rate) times.push_back(t); times.push_back(stop); // create the animation animation a; a.name = clipName.asChar(); if(m_animations.size() == 0) { a.startTime = 0; a.endTime = times[times.size()-1] - times[0]; } else { a.startTime = m_animations[m_animations.size()-1].endTime + 1; a.endTime = a.startTime + times[times.size()-1] - times[0]; } m_animations.push_back(a); int animIdx = m_animations.size() - 1; for (i=0; i<times.size(); i++) { MAnimControl::setCurrentTime(MTime(times[i],MTime::uiUnit())); for (j=0; j<m_joints.size(); j++) { keyframeTranslation translation; keyframeRotation rotation; keyframeScale scale; joint &jt = m_joints[j]; int time = times[i] - times[0] + a.startTime; loadKeyframe(m_joints[j],time,translation,rotation,scale); translation.time *= frameTime; rotation.time *= frameTime; scale.time *= frameTime; size_t size = jt.keyframesTranslation.size(); if(size > 0) { keyframeTranslation& t = jt.keyframesTranslation[size - 1]; if(!equal(translation.v[0],t.v[0]) || !equal(translation.v[1],t.v[1]) || !equal(translation.v[2],t.v[2])) { //如果跟上一次不一样,并且跨越了桢,那么需要补一桢 int lastTime = Round(t.time / frameTime); if(time - 1 > lastTime) { keyframeTranslation temp = t; temp.time = (time - 1) * frameTime; jt.keyframesTranslation.push_back(temp); } jt.keyframesTranslation.push_back(translation); } } else { jt.keyframesTranslation.push_back(translation); } MFnIkJoint jn(jt.jointDag); if(jn.name() == "Hips") { // breakable; } size = jt.keyframesRotation.size(); if(size > 0) { keyframeRotation& r = jt.keyframesRotation[size - 1]; if(!equal(rotation.q[0],r.q[0]) || !equal(rotation.q[1],r.q[1]) || !equal(rotation.q[2],r.q[2]) || !equal(rotation.q[3],r.q[3])) { //如果跟上一次不一样,并且跨越了桢,那么需要补一桢 int lastTime = Round(r.time / frameTime); if(time - 1 > lastTime) { keyframeRotation temp = r; temp.time = (time - 1) * frameTime; jt.keyframesRotation.push_back(temp); } jt.keyframesRotation.push_back(rotation); } } else { jt.keyframesRotation.push_back(rotation); } size = jt.keyframesScale.size(); if(size > 0) { keyframeScale& s = jt.keyframesScale[size - 1]; if(!equal(scale.v[0],s.v[0]) || !equal(scale.v[1],s.v[1]) || !equal(scale.v[2],s.v[2])) { //如果跟上一次不一样,并且跨越了桢,那么需要补一桢 int lastTime = Round(s.time / frameTime); if(time - 1 > lastTime) { keyframeScale temp = s; temp.time = (time - 1) * frameTime; jt.keyframesScale.push_back(temp); } jt.keyframesScale.push_back(scale); } } else { jt.keyframesScale.push_back(scale); } if(jt.hasRibbonSystem) { keyframeT<bool> keyframeVisible; keyframeT<float> keyframeAbove; keyframeT<float> keyframeBelow; keyframeT<short> keyframeSlot; keyframeT<float3> keyframeColor; keyframeT<float> keyframeAlpha; MFnIkJoint jointFn(jt.jointDag); MPlug plug; plug = jointFn.findPlug("unRibbonVisible"); bool visible; plug.getValue(visible); plug = jointFn.findPlug("unRibbonAbove"); float above; plug.getValue(above); plug = jointFn.findPlug("unRibbonBelow"); float below; plug.getValue(below); plug = jointFn.findPlug("unRibbonTextureSlot"); short slot; plug.getValue(slot); plug = jointFn.findPlug("unRibbonVertexColor"); MObject object; plug.getValue(object); MFnNumericData data(object); float r,g,b; data.getData(r,g,b); plug = jointFn.findPlug("unRibbonVertexAlpha"); float alpha; plug.getValue(alpha); keyframeVisible.time = time * frameTime; keyframeAbove.time = time * frameTime; keyframeBelow.time = time * frameTime; keyframeSlot.time = time * frameTime; keyframeColor.time = time * frameTime; keyframeAlpha.time = time * frameTime; keyframeVisible.data = visible; keyframeAbove.data = above; keyframeBelow.data = below; keyframeSlot.data = slot; keyframeColor.data[0] = r; keyframeColor.data[1] = g; keyframeColor.data[2] = b; keyframeAlpha.data = alpha; addKeyFramesBool(&jt.ribbon.keyframesVisible,&keyframeVisible); addKeyFramesFloat(&jt.ribbon.keyframeAbove,&keyframeAbove); addKeyFramesFloat(&jt.ribbon.keyframeBelow,&keyframeBelow); size = jt.ribbon.keyframeSlot.size(); if(size > 0) { keyframeT<short>& s = jt.ribbon.keyframeSlot[size - 1]; if(s.data == slot) { jt.ribbon.keyframeSlot.push_back(keyframeSlot); } } else { jt.ribbon.keyframeSlot.push_back(keyframeSlot); } size = jt.ribbon.keyframeColor.size(); if(size > 0) { keyframeT<float3>& s = jt.ribbon.keyframeColor[size - 1]; if(!equal(s.data[0],r) || !equal(s.data[1],g) || !equal(s.data[2],b)) { jt.ribbon.keyframeColor.push_back(keyframeColor); } } else { jt.ribbon.keyframeColor.push_back(keyframeColor); } addKeyFramesFloat(&jt.ribbon.keyframeAlpha,&keyframeAlpha); } if(jt.hasParticleSystem) { keyframeT<bool> keyframeVisible; keyframeT<float> keyframeSpeed; keyframeT<float> keyframeVariation; keyframeT<float> keyframeConeAngle; keyframeT<float> keyframeGravity; keyframeT<float> keyframeExplosiveForce; keyframeT<float> keyframeEmissionRate; keyframeT<float> keyframeWidth; keyframeT<float> keyframeLength; keyframeT<float> keyframeHeight; MFnIkJoint jointFn(jt.jointDag); MPlug plug; plug = jointFn.findPlug("unParticleVisible"); bool visible; plug.getValue(visible); plug = jointFn.findPlug("unParticleSpeed"); float speed; plug.getValue(speed); plug = jointFn.findPlug("unParticleVariationPercent"); float variation; plug.getValue(variation); plug = jointFn.findPlug("unParticleConeAngle"); float coneAngle; plug.getValue(coneAngle); plug = jointFn.findPlug("unParticleGravity"); float gravity; plug.getValue(gravity); plug = jointFn.findPlug("unParticleExplosiveForce"); float explosiveForce = 0.0f; if(!plug.isNull()) { plug.getValue(explosiveForce); } plug = jointFn.findPlug("unParticleEmissionRate"); float emissionRate; plug.getValue(emissionRate); plug = jointFn.findPlug("unParticleEmitterWidth"); float width; plug.getValue(width); plug = jointFn.findPlug("unParticleEmitterLength"); float length; plug.getValue(length); plug = jointFn.findPlug("unParticleEmitterHeight"); float height = 0.0f; if(!plug.isNull()) { plug.getValue(height); } keyframeVisible.time = time * frameTime; keyframeSpeed.time = time * frameTime; keyframeVariation.time = time * frameTime; keyframeConeAngle.time = time * frameTime; keyframeGravity.time = time * frameTime; keyframeExplosiveForce.time = time * frameTime; keyframeEmissionRate.time = time * frameTime; keyframeWidth.time = time * frameTime; keyframeLength.time = time * frameTime; keyframeHeight.time = time * frameTime; keyframeVisible.data = visible; keyframeSpeed.data = speed; keyframeVariation.data = variation / 100.0f; keyframeConeAngle.data = coneAngle; keyframeGravity.data = gravity; keyframeExplosiveForce.data = explosiveForce; keyframeEmissionRate.data = emissionRate; keyframeWidth.data = width; keyframeLength.data = length; keyframeHeight.data = height; addKeyFramesBool(&jt.particle.keyframesVisible,&keyframeVisible); addKeyFramesFloat(&jt.particle.keyframesSpeed,&keyframeSpeed); addKeyFramesFloat(&jt.particle.keyframesVariation,&keyframeVariation); addKeyFramesFloat(&jt.particle.keyframesConeAngle,&keyframeConeAngle); addKeyFramesFloat(&jt.particle.keyframesGravity,&keyframeGravity); addKeyFramesFloat(&jt.particle.keyframesExplosiveForce,&keyframeExplosiveForce); addKeyFramesFloat(&jt.particle.keyframesEmissionRate,&keyframeEmissionRate); addKeyFramesFloat(&jt.particle.keyframesWidth,&keyframeWidth); addKeyFramesFloat(&jt.particle.keyframesLength,&keyframeLength); addKeyFramesFloat(&jt.particle.keyframesHeight,&keyframeHeight); } } } return MS::kSuccess; }