public static void RegisterObject(Animatable obj, bool createInitialKeys = true) { objects.Add(obj); var trans = obj.transform; if (createInitialKeys) { obj.StartFrame = CurFrame; obj.AddTranslationKey(trans.localPosition, 0); obj.AddRotationKey(trans.localRotation, 0); obj.AddScaleKey(trans.localScale, 0); } }
private static void SetPropertiesFromJsonObject(Animatable sceneObject, SerializableAnimatable obj) { TimeManager.RegisterObject(sceneObject, false); sceneObject.StartFrame = obj.StartFrame; foreach (var pair in obj.TranslationKeys) { sceneObject.AddTranslationKey(pair.Item2, pair.Item1 + obj.StartFrame); } foreach (var pair in obj.RotationKeys) { sceneObject.AddRotationKey(pair.Item2, pair.Item1 + obj.StartFrame); } foreach (var pair in obj.ScaleKeys) { sceneObject.AddScaleKey(pair.Item2, pair.Item1 + obj.StartFrame); } sceneObject.EvaluateTransform(0); // recurse for top-level folks if (obj.IsTopLevel) { var sceneChildren = sceneObject.GetComponentsInChildren <Animatable>(); Debug.Assert(sceneChildren.Length - 1 == obj.Children.Count, "#children in saved file differs from loaded object! " + sceneChildren.Length + " != " + obj.Children.Count); // Since GetComponentsInChildren<T> uses depth-first search, the first // component must be `obj` itself, which we skip for (int i = 1; i < sceneChildren.Length; ++i) { SetPropertiesFromJsonObject(sceneChildren[i], obj.Children[i - 1]); } } }
// Update is called once per frame void Update() { bool newFrame = false; if (IsAnimationPlaying && !IsRecording && (DateTime.Now - lastFrameTime).TotalSeconds < Globals.INV_FPS) { return; } else if (IsAnimationPlaying) { if (Mathf.FloorToInt((float)(DateTime.Now - lastFrameTime).TotalSeconds * Globals.FPS) > 0) { // Use FPS to determine which frame to move to (NOTE: this might skip frames) CurFrame = CurFrame + Mathf.FloorToInt((float)(DateTime.Now - lastFrameTime).TotalSeconds * Globals.FPS); // Store ideal execution time for this frame lastFrameTime = DateTime.Now.AddSeconds(-((DateTime.Now - lastFrameTime).TotalSeconds % Globals.INV_FPS)); newFrame = true; } //automatically add more frames if needed if (controlledObject != null && CurFrame >= NumFrame) { Debug.Log("Adding additional frames: " + NumFrame + " -> " + (CurFrame + 1)); NumFrame = CurFrame + 1; } CurFrame = CurFrame % NumFrame; foreach (var obj in objects) { obj.EvaluateTransform(CurFrame); } } if (controlledObject != null) { switch (GestureManager.RecognitionState) { case GestureRecognizerState.Translating: var curHandPosition = poseManager.GetHandTransform(OvrAvatar.HandType.Right, PoseManager.HandJoint.IndexTip).position; var addVector = (controlledObject.transform.parent == null) ? (curHandPosition - initialHandPosition) : controlledObject.transform.parent.InverseTransformVector(curHandPosition - initialHandPosition); var position = initialObjectPose.transform.localPosition + addVector; if (newFrame) { controlledObject.AddTranslationKey(position, CurFrame); } else { controlledObject.transform.localPosition = position; } break; case GestureRecognizerState.Scaling: var curInterHandDistance = ( poseManager.GetHandTransform(OvrAvatar.HandType.Right, PoseManager.HandJoint.IndexTip).position - poseManager.GetHandTransform(OvrAvatar.HandType.Left, PoseManager.HandJoint.IndexTip).position ).magnitude; var scale = initialObjectPose.transform.localScale * (curInterHandDistance / (initialInterHandDistance + float.Epsilon)); if (newFrame) { controlledObject.AddScaleKey(scale, CurFrame); } else { controlledObject.transform.localScale = scale; } break; case GestureRecognizerState.Rotating: var rotation = ComputeCurrentRotation(); rotation = ((initialObjectPose.transform.parent == null) ? Quaternion.identity : Quaternion.Inverse(initialObjectPose.transform.parent.rotation)) * rotation; if (newFrame) { controlledObject.AddRotationKey(rotation, CurFrame); } else { controlledObject.transform.localRotation = rotation; } break; } if (newFrame) { controlledObject.EvaluateTransform(CurFrame); } } SetFrameCounterText(); }