public SampleAnimation ( |
||
animation | ||
time | float | |
return | void |
static public int SampleAnimation(IntPtr l) { try{ UnityEngine.GameObject self = (UnityEngine.GameObject)checkSelf(l); UnityEngine.AnimationClip a1; checkType(l, 2, out a1); System.Single a2; checkType(l, 3, out a2); self.SampleAnimation(a1, a2); return(0); } catch (Exception e) { LuaDLL.luaL_error(l, e.ToString()); return(0); } }
static public int SampleAnimation(IntPtr l) { try { UnityEngine.GameObject self = (UnityEngine.GameObject)checkSelf(l); UnityEngine.AnimationClip a1; checkType(l, 2, out a1); System.Single a2; checkType(l, 3, out a2); self.SampleAnimation(a1, a2); pushValue(l, true); return(1); } catch (Exception e) { return(error(l, e)); } }
static int SampleAnimation(IntPtr L) { try { ToLua.CheckArgsCount(L, 3); UnityEngine.GameObject obj = (UnityEngine.GameObject)ToLua.CheckObject(L, 1, typeof(UnityEngine.GameObject)); UnityEngine.AnimationClip arg0 = (UnityEngine.AnimationClip)ToLua.CheckUnityObject(L, 2, typeof(UnityEngine.AnimationClip)); float arg1 = (float)LuaDLL.luaL_checknumber(L, 3); obj.SampleAnimation(arg0, arg1); return(0); } catch (Exception e) { return(LuaDLL.toluaL_exception(L, e)); } }
void StopAnim(GameObject agent){ if (agent.GetComponent<ArmAnimator>().ArmC == null || agent.GetComponent<TorsoAnimator>().TorsoC == null) { Debug.Log ("Controller not assigned"); return; } if (agent.animation.isPlaying) { agent.SampleAnimation(agent.animation.clip, 0); //instead of rewind agent.animation.Stop(); } }
public override void Analyze(GameObject o) { Debug.Log("Starting analysis"); gameObject = o; name = animation.name; m_samples = 50; // Initialize legs and cycle data legC = gameObject.GetComponent(typeof(LegController)) as LegController; legs = legC.legs.Length; m_cycles = new LegCycleData[legs]; for (int leg=0; leg<legs; leg++) { cycles[leg] = new LegCycleData(); cycles[leg].samples = new LegCycleSample[samples+1]; for (int i=0; i<samples+1; i++) { cycles[leg].samples[i] = new LegCycleSample(); } cycles[leg].debugInfo = new CycleDebugInfo(); } graphMin = new Vector3(0, 1000, 1000); graphMax = new Vector3(0,-1000,-1000); for (int leg=0; leg<legs; leg++) { // Sample ankle, heel, toe, and toetip positions over the length of the animation. Transform ankleT = legC.legs[leg].ankle; Transform toeT = legC.legs[leg].toe; float rangeMax = 0; float ankleMin; float ankleMax; float toeMin; float toeMax; ankleMin = 1000; ankleMax = -1000; toeMin = 1000; toeMax = -1000; for (int i=0; i<samples+1; i++) { LegCycleSample s = cycles[leg].samples[i]; gameObject.SampleAnimation(animation,i*1.0f/samples*animation.length); s.ankleMatrix = Util.RelativeMatrix(ankleT,gameObject.transform); s.toeMatrix = Util.RelativeMatrix(toeT,gameObject.transform); s.heel = s.ankleMatrix.MultiplyPoint(legC.legs[leg].ankleHeelVector); s.toetip = s.toeMatrix.MultiplyPoint(legC.legs[leg].toeToetipVector); s.middle = (s.heel+s.toetip)/2; // For each sample in time we want to know if the heel or toetip is closer to the ground. // We need a smooth curve with 0 = ankle is closer and 1 = toe is closer. s.balance = MotionAnalyzer.GetFootBalance(s.heel.y, s.toetip.y, legC.legs[leg].footLength); // Find the minimum and maximum extends on all axes of the ankle and toe positions. ankleMin = Mathf.Min(ankleMin,s.heel.y); toeMin = Mathf.Min(toeMin,s.toetip.y); ankleMax = Mathf.Max(ankleMax,s.heel.y); toeMax = Mathf.Max(toeMax,s.toetip.y); } rangeMax = Mathf.Max(ankleMax-ankleMin,toeMax-toeMin); // Determine motion type /*if (motionType==MotionType.AutoDetect) { motionType = MotionType.WalkCycle; }*/ if (motionType==MotionType.WalkCycle) { FindCycleAxis(leg); // Foot stance time // Find the time when the foot stands most firmly on the ground. float stanceValue = Mathf.Infinity; for (int i=0; i<samples+1; i++) { LegCycleSample s = cycles[leg].samples[i]; float sampleValue = // We want the point in time when the max of the heel height and the toe height is lowest Mathf.Max(s.heel.y, s.toetip.y)/rangeMax // Add some bias to poses where the leg is in the middle of the swing // i.e. the foot position is close to the middle of the foot curve +Mathf.Abs( Util.ProjectOntoPlane(s.middle-cycles[leg].cycleCenter, Vector3.up).magnitude )/cycles[leg].cycleScaling; // Use the new value if it is lower (better). if (sampleValue<stanceValue) { cycles[leg].stanceIndex = i; stanceValue = sampleValue; } } } else { cycles[leg].cycleDirection = Vector3.forward; cycles[leg].cycleScaling = 0; cycles[leg].stanceIndex = 0; } // The stance time cycles[leg].stanceTime = GetTimeFromIndex(cycles[leg].stanceIndex); // The stance index sample LegCycleSample ss = cycles[leg].samples[cycles[leg].stanceIndex]; // Sample the animation at stance time gameObject.SampleAnimation(animation,cycles[leg].stanceTime*animation.length); // Using the stance sample as reference we can now determine: // The vector from heel to toetip at the stance pose cycles[leg].heelToetipVector = ( ss.toeMatrix.MultiplyPoint(legC.legs[leg].toeToetipVector) - ss.ankleMatrix.MultiplyPoint(legC.legs[leg].ankleHeelVector) ); cycles[leg].heelToetipVector = Util.ProjectOntoPlane(cycles[leg].heelToetipVector, Vector3.up); cycles[leg].heelToetipVector = cycles[leg].heelToetipVector.normalized * legC.legs[leg].footLength; // Calculate foot flight path based on weighted average between ankle flight path and toe flight path, // using foot balance as weight. // The distance between ankle and toe is accounted for, using the stance pose for reference. for (int i=0; i<samples+1; i++) { LegCycleSample s = cycles[leg].samples[i]; s.footBase = ( (s.heel)*(1-s.balance) +(s.toetip-cycles[leg].heelToetipVector)*(s.balance) ); } // The position of the footbase in the stance pose cycles[leg].stancePosition = ss.footBase; cycles[leg].stancePosition.y = legC.groundPlaneHeight; if (motionType==MotionType.WalkCycle) { // Find contact times: // Strike time: foot first touches the ground (0% grounding) // Down time: all of the foot touches the ground (100% grounding) // Lift time: all of the foot still touches the ground but begins to lift (100% grounding) // Liftoff time: last part of the foot leaves the ground (0% grounding) float timeA; float timeB; // Find upwards contact times for projected ankle and toe // Use the first occurance as lift time and the second as liftoff time timeA = FindContactTime(cycles[leg], false, +1, rangeMax, 0.1f); cycles[leg].debugInfo.ankleLiftTime = timeA; timeB = FindContactTime(cycles[leg], true, +1, rangeMax, 0.1f); cycles[leg].debugInfo.toeLiftTime = timeB; if (timeA<timeB) { cycles[leg].liftTime = timeA; cycles[leg].liftoffTime = timeB; } else { cycles[leg].liftTime = timeB; cycles[leg].liftoffTime = timeA; } // Find time where swing direction and speed changes significantly. // If this happens sooner than the found liftoff time, // then the liftoff time must be overwritten with this value. timeA = FindSwingChangeTime(cycles[leg], +1, 0.5f); cycles[leg].debugInfo.footLiftTime = timeA; if (cycles[leg].liftoffTime > timeA) { cycles[leg].liftoffTime = timeA; if (cycles[leg].liftTime > cycles[leg].liftoffTime) { cycles[leg].liftTime = cycles[leg].liftoffTime; } } // Find downwards contact times for projected ankle and toe // Use the first occurance as strike time and the second as down time timeA = FindContactTime(cycles[leg], false, -1, rangeMax, 0.1f); timeB = FindContactTime(cycles[leg], true, -1, rangeMax, 0.1f); if (timeA<timeB) { cycles[leg].strikeTime = timeA; cycles[leg].landTime = timeB; } else { cycles[leg].strikeTime = timeB; cycles[leg].landTime = timeA; } // Find time where swing direction and speed changes significantly. // If this happens later than the found strike time, // then the strike time must be overwritten with this value. timeA = FindSwingChangeTime(cycles[leg], -1, 0.5f); cycles[leg].debugInfo.footLandTime = timeA; if (cycles[leg].strikeTime < timeA) { cycles[leg].strikeTime = timeA; if (cycles[leg].landTime < cycles[leg].strikeTime) { cycles[leg].landTime = cycles[leg].strikeTime; } } // Set postliftTime and prelandTime float softening = 0.2f; cycles[leg].postliftTime = cycles[leg].liftoffTime; if (cycles[leg].postliftTime < cycles[leg].liftTime+softening) { cycles[leg].postliftTime = cycles[leg].liftTime+softening; } cycles[leg].prelandTime = cycles[leg].strikeTime; if (cycles[leg].prelandTime > cycles[leg].landTime-softening) { cycles[leg].prelandTime = cycles[leg].landTime-softening; } // Calculate the distance traveled during one cycle (for this foot). Vector3 stanceSlideVector = ( cycles[leg].samples[GetIndexFromTime(Util.Mod(cycles[leg].liftoffTime+cycles[leg].stanceTime))].footBase -cycles[leg].samples[GetIndexFromTime(Util.Mod(cycles[leg].strikeTime+cycles[leg].stanceTime))].footBase ); // FIXME: Assumes horizontal ground plane stanceSlideVector.y = 0; cycles[leg].cycleDistance = stanceSlideVector.magnitude/(cycles[leg].liftoffTime-cycles[leg].strikeTime+1); cycles[leg].cycleDirection = -(stanceSlideVector.normalized); } else { cycles[leg].cycleDirection = Vector3.zero; cycles[leg].cycleDistance = 0; } graphMax.y = Mathf.Max(graphMax.y,Mathf.Max(ankleMax,toeMax)); } // Find the overall speed and direction traveled during one cycle, // based on average of speed values for each individual foot. // (They should be very close, but animations are often imperfect, // leading to different speeds for different legs.) m_cycleDistance = 0; m_cycleDirection = Vector3.zero; for (int leg=0; leg<legs; leg++) { m_cycleDistance += cycles[leg].cycleDistance; m_cycleDirection += cycles[leg].cycleDirection; Debug.Log("Cycle direction of leg "+leg+" is "+cycles[leg].cycleDirection+" with step distance "+cycles[leg].cycleDistance); } m_cycleDistance /= legs; m_cycleDirection /= legs; m_cycleDuration = animation.length; m_cycleSpeed = cycleDistance/cycleDuration; Debug.Log("Overall cycle direction is "+m_cycleDirection+" with step distance "+m_cycleDistance+" and speed "+m_cycleSpeed); nativeSpeed = m_cycleSpeed * gameObject.transform.localScale.x; // Calculate normalized foot flight path for (int leg=0; leg<legs; leg++) { if (motionType==MotionType.WalkCycle) { for (int j=0; j<samples; j++) { int i = Util.Mod(j+cycles[leg].stanceIndex,samples); LegCycleSample s = cycles[leg].samples[i]; float time = GetTimeFromIndex(j); s.footBaseNormalized = s.footBase; if (fixFootSkating) { // Calculate normalized foot flight path // based on the calculated cycle distance of each individual foot Vector3 reference = ( -cycles[leg].cycleDistance * cycles[leg].cycleDirection * (time-cycles[leg].liftoffTime) +cycles[leg].samples[ GetIndexFromTime(cycles[leg].liftoffTime+cycles[leg].stanceTime) ].footBase ); s.footBaseNormalized = (s.footBaseNormalized-reference); if (cycles[leg].cycleDirection!=Vector3.zero) { s.footBaseNormalized = Quaternion.Inverse( Quaternion.LookRotation(cycles[leg].cycleDirection) ) * s.footBaseNormalized; } s.footBaseNormalized.z /= cycles[leg].cycleDistance; if (time<=cycles[leg].liftoffTime) { s.footBaseNormalized.z = 0; } if (time>=cycles[leg].strikeTime) { s.footBaseNormalized.z = 1; } s.footBaseNormalized.y = s.footBase.y - legC.groundPlaneHeight; } else { // Calculate normalized foot flight path // based on the cycle distance of the whole motion // (the calculated average cycle distance) Vector3 reference = ( -m_cycleDistance * m_cycleDirection * (time-cycles[leg].liftoffTime*0) // FIXME: Is same as stance position: +cycles[leg].samples[ GetIndexFromTime(cycles[leg].liftoffTime*0+cycles[leg].stanceTime) ].footBase ); s.footBaseNormalized = (s.footBaseNormalized-reference); if (cycles[leg].cycleDirection!=Vector3.zero) { s.footBaseNormalized = Quaternion.Inverse( Quaternion.LookRotation(m_cycleDirection) ) * s.footBaseNormalized; } s.footBaseNormalized.z /= m_cycleDistance; s.footBaseNormalized.y = s.footBase.y - legC.groundPlaneHeight; } } //cycles[leg].samples[cycles[leg].stanceIndex].footBaseNormalized.z = 0; cycles[leg].samples[samples] = cycles[leg].samples[0]; } else { for (int j=0; j<samples; j++) { int i = Util.Mod(j+cycles[leg].stanceIndex,samples); LegCycleSample s = cycles[leg].samples[i]; s.footBaseNormalized = s.footBase - cycles[leg].stancePosition; } } } for (int leg=0; leg<legs; leg++) { float heelToeZDist = Vector3.Dot(cycles[leg].heelToetipVector,cycleDirection); for (int i=0; i<samples; i++) { LegCycleSample s = cycles[leg].samples[i]; float zVal = Vector3.Dot(s.footBase, cycleDirection); if (zVal < graphMin.z) graphMin.z = zVal; if (zVal > graphMax.z) graphMax.z = zVal; if (zVal+heelToeZDist < graphMin.z) graphMin.z = zVal+heelToeZDist; if (zVal+heelToeZDist > graphMax.z) graphMax.z = zVal+heelToeZDist; } } graphMin.y = legC.groundPlaneHeight; }