Beispiel #1
0
        public void GetTotalDuration()
        {
            var animation = new AnimationClip<float>
              {
            Animation = new SingleFromToByAnimation { Duration = TimeSpan.FromSeconds(1.0) },
            Delay = TimeSpan.FromSeconds(10),
            Duration = null,
            Speed = 1.0f,
              };

              // Default duration is 1 second.
              Assert.AreEqual(TimeSpan.FromSeconds(11.0), animation.GetTotalDuration());

              animation.Duration = TimeSpan.FromSeconds(5.0);
              Assert.AreEqual(TimeSpan.FromSeconds(15.0), animation.GetTotalDuration());

              animation.Speed = 2.0f;
              Assert.AreEqual(TimeSpan.FromSeconds(12.5), animation.GetTotalDuration());

              animation.Delay = TimeSpan.FromSeconds(-1.0);
              Assert.AreEqual(TimeSpan.FromSeconds(1.5), animation.GetTotalDuration());

              animation.Speed = 0.0f;
              Assert.AreEqual(TimeSpan.MaxValue, animation.GetTotalDuration());
        }
Beispiel #2
0
    private void RestartAnimations()
    {
      // Start original animation on one model.
      var loopingAnimation = new AnimationClip<SkeletonPose>(_animation)
      {
        LoopBehavior = LoopBehavior.Cycle,
        Duration = TimeSpan.MaxValue,
      };
      AnimationService.StartAnimation(loopingAnimation, (IAnimatableProperty)_meshNodeUncompressed.SkeletonPose);

      // Clone the original animation.
      var animationCompressed = _animation.Clone();

      // Compress animation. This removes key frames that can be computed from neighboring frames.
      // This animation is lossy and the parameters define the allowed error.
      _removedKeyFrames = animationCompressed.Compress(0.01f, _rotationCompressionThreshold, 0.001f);

      // Finalize the SkeletonKeyFrameAnimation. 
      // (This must be called to optimize the internal data structures.)
      animationCompressed.Freeze();

      // Start compressed animation on the other model.
      var loopingAnimationCompressed = new AnimationClip<SkeletonPose>(animationCompressed)
      {
        LoopBehavior = LoopBehavior.Cycle,
        Duration = TimeSpan.MaxValue,
      };
      AnimationService.StartAnimation(loopingAnimationCompressed, (IAnimatableProperty)_meshNodeCompressed.SkeletonPose);
    }
        public ModelContainer(Model modelpass, Pose posepass, SkeletonPose skeletonpass)
        {
            _model = modelpass;
            _pose = posepass;
            _skeleton = skeletonpass;

            var additionalData = (Dictionary<string,object>)_model.Tag;
            var animations = (Dictionary<string, SkeletonKeyFrameAnimation>)additionalData["Animations"];
            int index = 0;

            _animations = new ITimeline[animations.Count];

                _animations[0] = new AnimationClip<SkeletonPose>(animations["First"])
                {
                    LoopBehavior = LoopBehavior.Cycle,
                    Duration = TimeSpan.MaxValue
                };
                index++;

                _animations[1] = new AnimationClip<SkeletonPose>(animations["Second"]);

                _animations[2] = new AnimationClip<SkeletonPose>(animations["Second"])
                {
                    LoopBehavior = LoopBehavior.Cycle,
                    Duration = TimeSpan.MaxValue
                };
        }
        public void TestAnimationClip()
        {
            var clip = new AnimationClip
            {
                Duration = TimeSpan.FromSeconds(2.0f),
                RepeatMode = AnimationRepeatMode.LoopInfinite
            };

            var testCurve = new AnimationCurve<float>();
            clip.AddCurve("posx[TestNode]", testCurve);
            testCurve.InterpolationType = AnimationCurveInterpolationType.Linear;

            var time = CompressedTimeSpan.FromSeconds(0.0f);
            var value = 0.0f;
            var frame0 = new KeyFrameData<float>(time, value);
            testCurve.KeyFrames.Add(frame0);

            time = CompressedTimeSpan.FromSeconds(1.0f);
            value = 1.0f;
            var frame1 = new KeyFrameData<float>(time, value);
            testCurve.KeyFrames.Add(frame1);

            clip.Optimize();

            //we should have 3 frames at this point. the last one will be added by the optimization process...
            Assert.That(clip.OptimizedCurvesFloat.AnimationSortedValueCount, Is.EqualTo(1));
            //And 2 initial frames            
            Assert.That(clip.OptimizedCurvesFloat.AnimationInitialValues[0].Value1, Is.EqualTo(frame0));
            Assert.That(clip.OptimizedCurvesFloat.AnimationInitialValues[0].Value2, Is.EqualTo(frame1));
            Assert.That(clip.OptimizedCurvesFloat.AnimationSortedValues.Length, Is.EqualTo(1));
            Assert.That(clip.OptimizedCurvesFloat.AnimationSortedValues[0].Length, Is.EqualTo(1));
            Assert.That(clip.OptimizedCurvesFloat.AnimationSortedValues[0][0].Value, Is.EqualTo(frame1));
        }
Beispiel #5
0
    public BoneJiggleSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      var modelNode = ContentManager.Load<ModelNode>("Dude/Dude");
      _meshNode = modelNode.GetSubtree().OfType<MeshNode>().First().Clone();
      _meshNode.PoseLocal = new Pose(new Vector3F(0, 0, 0), Matrix33F.CreateRotationY(ConstantsF.Pi));
      SampleHelper.EnablePerPixelLighting(_meshNode);
      GraphicsScreen.Scene.Children.Add(_meshNode);

      var animations = _meshNode.Mesh.Animations;
      var walkAnimation = new AnimationClip<SkeletonPose>(animations.Values.First())
      {
        LoopBehavior = LoopBehavior.Cycle,
        Duration = TimeSpan.MaxValue,
      };
      _walkAnimationController = AnimationService.StartAnimation(walkAnimation, (IAnimatableProperty)_meshNode.SkeletonPose);
      _walkAnimationController.AutoRecycle();

      // Create a BoneJiggler instance for the head bone (bone index 7).
      _boneJiggler = new BoneJiggler(_meshNode.SkeletonPose, 7, new Vector3F(1.1f, 0, 0))
      {
        Spring = 100,
        Damping = 3,
      };
    }
Beispiel #6
0
    public AttachmentSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      var modelNode = ContentManager.Load<ModelNode>("Marine/PlayerMarine");
      _meshNode = modelNode.GetSubtree().OfType<MeshNode>().First().Clone();
      SampleHelper.EnablePerPixelLighting(_meshNode);
      GraphicsScreen.Scene.Children.Add(_meshNode);

      // Play a looping 'Idle' animation.
      var animations = _meshNode.Mesh.Animations;
      var idleAnimation = animations["Idle"];
      var loopingAnimation = new AnimationClip<SkeletonPose>(idleAnimation)
      {
        LoopBehavior = LoopBehavior.Cycle,
        Duration = TimeSpan.MaxValue,
      };
      var animationController = AnimationService.StartAnimation(loopingAnimation, (IAnimatableProperty)_meshNode.SkeletonPose);
      animationController.UpdateAndApply();
      animationController.AutoRecycle();

      // Add weapon model to the scene graph under the node of the marine mesh.
      _weaponModelNode = ContentManager.Load<ModelNode>("Marine/Weapon/WeaponMachineGun").Clone();
      _meshNode.Children = new SceneNodeCollection();
      _meshNode.Children.Add(_weaponModelNode);
    }
Beispiel #7
0
        public void CyclicLoopBehavior()
        {
            var keyFrame0 = new KeyFrame<QuaternionF>(TimeSpan.FromSeconds(0.0), _random.NextQuaternionF());
              var keyFrame1 = new KeyFrame<QuaternionF>(TimeSpan.FromSeconds(1.0), _random.NextQuaternionF());
              var keyFrame2 = new KeyFrame<QuaternionF>(TimeSpan.FromSeconds(2.0), _random.NextQuaternionF());
              var animation = new QuaternionFKeyFrameAnimation();
              animation.KeyFrames.Add(keyFrame0);
              animation.KeyFrames.Add(keyFrame1);
              animation.KeyFrames.Add(keyFrame2);

              var animationClip = new AnimationClip<QuaternionF> { Animation = animation };
              animationClip.LoopBehavior = LoopBehavior.Cycle;
              animationClip.Duration = TimeSpan.MaxValue;
              animationClip.ClipOffset = TimeSpan.FromSeconds(-1);

              var defaultSource = _random.NextQuaternionF();
              var defaultTarget = _random.NextQuaternionF();

              // Pre loop
              var expected = InterpolationHelper.Lerp(keyFrame1.Value, keyFrame2.Value, 0.25f);
              Assert.AreEqual(expected, animationClip.GetValue(TimeSpan.FromSeconds(0.25), defaultSource, defaultTarget));

              // Post loop
              expected = InterpolationHelper.Lerp(keyFrame1.Value, keyFrame2.Value, 0.75f);
              Assert.AreEqual(expected, animationClip.GetValue(TimeSpan.FromSeconds(4.75), defaultSource, defaultTarget));
        }
Beispiel #8
0
    public StringAnimationSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      // A key-frame animation of string values.
      // Note: The key frame animation plays all strings and then holds the last key frame
      // because the default KeyFrameAnimation.FillBehavior is "Hold".
      StringKeyFrameAnimation keyFrameAnimation = new StringKeyFrameAnimation();
      keyFrameAnimation.KeyFrames.Add(new KeyFrame<string>(TimeSpan.FromSeconds(0), "The"));
      keyFrameAnimation.KeyFrames.Add(new KeyFrame<string>(TimeSpan.FromSeconds(1), "quick"));
      keyFrameAnimation.KeyFrames.Add(new KeyFrame<string>(TimeSpan.FromSeconds(2), "brown"));
      keyFrameAnimation.KeyFrames.Add(new KeyFrame<string>(TimeSpan.FromSeconds(3), "fox"));
      keyFrameAnimation.KeyFrames.Add(new KeyFrame<string>(TimeSpan.FromSeconds(4), "jumps"));
      keyFrameAnimation.KeyFrames.Add(new KeyFrame<string>(TimeSpan.FromSeconds(5), "over"));
      keyFrameAnimation.KeyFrames.Add(new KeyFrame<string>(TimeSpan.FromSeconds(6), "the"));
      keyFrameAnimation.KeyFrames.Add(new KeyFrame<string>(TimeSpan.FromSeconds(7), "lazy"));
      keyFrameAnimation.KeyFrames.Add(new KeyFrame<string>(TimeSpan.FromSeconds(8), "dog."));

      // Use an AnimationClip to loop the first 9 seconds of the key-frame animation 
      // forever. The animation speed is set to 2 to make the animation play faster.
      AnimationClip<string> timelineClip = new AnimationClip<string>(keyFrameAnimation)
      {
        LoopBehavior = LoopBehavior.Cycle,
        ClipStart = TimeSpan.FromSeconds(0),
        ClipEnd = TimeSpan.FromSeconds(9),
        Duration = TimeSpan.MaxValue,
        Speed = 2,
      };

      // Start the animation.
      AnimationService.StartAnimation(timelineClip, _animatableString);
    }
Beispiel #9
0
        public void GetDefaultDurationTest()
        {
            var timelineGroup = new TimelineGroup();
              var animation = new Vector2FAnimation();
              var animation2 = new AnimationClip<float>
              {
            Animation = new SingleFromToByAnimation(),
            Delay = TimeSpan.FromSeconds(10),
              };
              var animation3 = new AnimationClip<float>
              {
            Animation = new SingleFromToByAnimation(),
            Delay = TimeSpan.FromSeconds(8),
            Duration = TimeSpan.FromSeconds(4),
              };

              Assert.AreEqual(TimeSpan.FromSeconds(0.0), timelineGroup.GetTotalDuration());

              timelineGroup.Add(animation);
              Assert.AreEqual(TimeSpan.FromSeconds(0.0), timelineGroup.GetTotalDuration());

              timelineGroup.Add(animation2);
              Assert.AreEqual(TimeSpan.FromSeconds(11.0), timelineGroup.GetTotalDuration());

              timelineGroup.Add(animation3);
              Assert.AreEqual(TimeSpan.FromSeconds(12.0), timelineGroup.GetTotalDuration());
        }
        protected override void LoadContent()
        {
            // Get dude model and start animation on the dude.
              _dudeModel = Game.Content.Load<Model>("Dude");
              var additionalData = (Dictionary<string, object>)_dudeModel.Tag;
              var skeleton = (Skeleton)additionalData["Skeleton"];
              _dudeSkeletonPose = SkeletonPose.Create(skeleton);
              var animations = (Dictionary<string, SkeletonKeyFrameAnimation>)additionalData["Animations"];
              var loopingAnimation = new AnimationClip<SkeletonPose>(animations.Values.First())
              {
            LoopBehavior = LoopBehavior.Cycle,
            Duration = TimeSpan.MaxValue,
              };
              AnimationService.StartAnimation(loopingAnimation, (IAnimatableProperty)_dudeSkeletonPose);

              // Get marine model - do not start any animations on the marine model.
              _marineModel = Game.Content.Load<Model>("PlayerMarine");
              additionalData = (Dictionary<string, object>)_marineModel.Tag;
              skeleton = (Skeleton)additionalData["Skeleton"];
              _marineSkeletonPose = SkeletonPose.Create(skeleton);

              CreateSkeletonMapper();

              base.LoadContent();
        }
Beispiel #11
0
    public SkeletonMappingSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      // Get dude model and start animation on the dude.
      var modelNode = ContentManager.Load<ModelNode>("Dude/Dude");
      _dudeMeshNode = modelNode.GetSubtree().OfType<MeshNode>().First().Clone();
      _dudeMeshNode.PoseLocal = new Pose(new Vector3F(-0.5f, 0, 0), Matrix33F.CreateRotationY(ConstantsF.Pi));
      SampleHelper.EnablePerPixelLighting(_dudeMeshNode);
      GraphicsScreen.Scene.Children.Add(_dudeMeshNode);

      var animations = _dudeMeshNode.Mesh.Animations;
      var loopingAnimation = new AnimationClip<SkeletonPose>(animations.Values.First())
      {
        LoopBehavior = LoopBehavior.Cycle,
        Duration = TimeSpan.MaxValue,
      };
      AnimationService.StartAnimation(loopingAnimation, (IAnimatableProperty)_dudeMeshNode.SkeletonPose);

      // Get marine model - do not start any animations on the marine model.
      modelNode = ContentManager.Load<ModelNode>("Marine/PlayerMarine");
      _marineMeshNode = modelNode.GetSubtree().OfType<MeshNode>().First().Clone();
      _marineMeshNode.PoseLocal = new Pose(new Vector3F(0.5f, 0, 0), Matrix33F.CreateRotationY(ConstantsF.Pi));
      SampleHelper.EnablePerPixelLighting(_marineMeshNode);
      GraphicsScreen.Scene.Children.Add(_marineMeshNode);

      CreateSkeletonMapper();
    }
        internal void Initialize(AnimationClip clip, List<AnimationBlender.Channel> channels)
        {
            this.BlenderChannels = channels;
            this.clip = clip;
            clip.Freeze();

            // If there are optimized curve data, instantiate appropriate evaluators
            if (clip.OptimizedCurvesFloat != null)
            {
                if (curveEvaluatorOptimizedFloat == null)
                    curveEvaluatorOptimizedFloat = new AnimationCurveEvaluatorOptimizedFloatGroup();
                curveEvaluatorOptimizedFloat.Initialize(clip.OptimizedCurvesFloat);
            }

            if (clip.OptimizedCurvesVector3 != null)
            {
                if (curveEvaluatorOptimizedVector3 == null)
                    curveEvaluatorOptimizedVector3 = new AnimationCurveEvaluatorOptimizedVector3Group();
                curveEvaluatorOptimizedVector3.Initialize(clip.OptimizedCurvesVector3);
            }

            if (clip.OptimizedCurvesQuaternion != null)
            {
                if (curveEvaluatorOptimizedQuaternion == null)
                    curveEvaluatorOptimizedQuaternion = new AnimationCurveEvaluatorOptimizedQuaternionGroup();
                curveEvaluatorOptimizedQuaternion.Initialize(clip.OptimizedCurvesQuaternion);
            }

            // Add already existing channels
            for (int index = 0; index < channels.Count; index++)
            {
                var channel = channels[index];
                AddChannel(ref channel);
            }
        }
Beispiel #13
0
    public BasicAnimationSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      var titleSafeArea = GraphicsService.GraphicsDevice.Viewport.TitleSafeArea;
      float minX = titleSafeArea.Left + 100;
      float maxX = titleSafeArea.Right - 100;

      // A from/to/by animation that animates a float value from minX to maxX over 2 seconds
      // using an easing function smooth movement.
      SingleFromToByAnimation xAnimation = new SingleFromToByAnimation
      {
        From = minX,
        To = maxX,
        Duration = TimeSpan.FromSeconds(2),
        EasingFunction = new CubicEase { Mode = EasingMode.EaseInOut },
      };

      // From-To-By animations do not loop by default.
      // Use an AnimationClip to turn the 2 second xAnimation into an animation that
      // oscillates forever.
      _oscillatingXAnimation = new AnimationClip<float>(xAnimation)
      {
        LoopBehavior = LoopBehavior.Oscillate,
        Duration = TimeSpan.MaxValue,
      };


      // A color key-frame animation.
      ColorKeyFrameAnimation colorAnimation = new ColorKeyFrameAnimation
      {
        //EnableInterpolation = true,  // Interpolation is enabled by default.
      };
      // Add the key-frames.
      colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(0.0), Color.Red));
      colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(0.5), Color.Orange));
      colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(1.0), Color.Yellow));
      colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(1.5), Color.Green));
      colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(2.0), Color.Blue));
      colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(2.5), Color.Indigo));
      colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(3.0), Color.Violet));

      // The last-key frame defines the length of the animation (3.5 seconds). This is a
      // "loop frame", which means the value is the same as in the first key to create a looping
      // animation.
      colorAnimation.KeyFrames.Add(new KeyFrame<Color>(TimeSpan.FromSeconds(3.5), Color.Red));

      // If the key-frames are not sorted, call Sort().
      //colorAnimation.KeyFrames.Sort();

      // Use an AnimationClip to turn the 3.5 second colorAnimation into an animation that
      // loops forever.
      _loopedColorAnimation = new AnimationClip<Color>(colorAnimation)
      {
        LoopBehavior = LoopBehavior.Cycle,
        Duration = TimeSpan.MaxValue,
      };

      StartAnimations();
    }
        public void Test_Indexer()
        {
            var anim = new AnimationController ();
            var clip = new AnimationClip (100, "Clip");
            anim.AddClip (clip);

            Assert.AreEqual (clip, anim["Clip"]);
        }
Beispiel #15
0
        public void Test_Play()
        {
            var clip = new AnimationClip (100, "ClipName");
            Assert.AreEqual (false, clip.IsPlaying);

            clip.Play ();

            Assert.AreEqual (true, clip.IsPlaying);
        }
 /// <summary>
 ///   <para>Automatically creates an AnimationClipPlayable for each supplied AnimationClip, then sets them as inputs to the mixer.</para>
 /// </summary>
 /// <param name="clips">AnimationClips to be used as inputs.</param>
 /// <returns>
 ///   <para>Returns false if the creation of the AnimationClipPlayables failed, or if the connection failed.</para>
 /// </returns>
 public bool SetInputs(AnimationClip[] clips)
 {
   if (clips == null)
     throw new NullReferenceException("Parameter clips was null. You need to pass in a valid array of clips.");
   AnimationPlayable[] animationPlayableArray = new AnimationPlayable[clips.Length];
   for (int index = 0; index < clips.Length; ++index)
     animationPlayableArray[index] = (AnimationPlayable) new AnimationClipPlayable(clips[index]);
   return this.SetInputs((IEnumerable<AnimationPlayable>) animationPlayableArray);
 }
Beispiel #17
0
        public void GetTotalDurationTest()
        {
            var animation = new AnimationClip<float>
              {
            Animation = new SingleFromToByAnimation
            {
              From = 100,
              To = 200,
              Duration = TimeSpan.FromSeconds(6.0),
            },
            Delay = TimeSpan.FromSeconds(10),
            Speed = 2,
            FillBehavior = FillBehavior.Hold,
              };

              var animation2 = new AnimationClip<float>
              {
            Animation = new SingleFromToByAnimation
            {
              From = 10,
              To = 20,
              Duration = TimeSpan.FromSeconds(5.0),
            },
            Delay = TimeSpan.Zero,
            Speed = 1,
            FillBehavior = FillBehavior.Hold,
              };

              var animationEx = new Vector4FAnimation();
              Assert.AreEqual(TimeSpan.FromSeconds(0.0), animationEx.GetTotalDuration());

              animationEx = new Vector4FAnimation();
              animationEx.W = animation;
              Assert.AreEqual(TimeSpan.FromSeconds(13.0), animationEx.GetTotalDuration());

              animationEx = new Vector4FAnimation();
              animationEx.X = animation;
              Assert.AreEqual(TimeSpan.FromSeconds(13.0), animationEx.GetTotalDuration());

              animationEx = new Vector4FAnimation();
              animationEx.Y = animation;
              Assert.AreEqual(TimeSpan.FromSeconds(13.0), animationEx.GetTotalDuration());

              animationEx = new Vector4FAnimation();
              animationEx.Z = animation;
              Assert.AreEqual(TimeSpan.FromSeconds(13.0), animationEx.GetTotalDuration());

              animationEx = new Vector4FAnimation();
              animationEx.W = animation;
              animationEx.X = animation2;
              Assert.AreEqual(TimeSpan.FromSeconds(13.0), animationEx.GetTotalDuration());

              animationEx = new Vector4FAnimation();
              animationEx.Y = animation2;
              animationEx.Z = animation;
              Assert.AreEqual(TimeSpan.FromSeconds(13.0), animationEx.GetTotalDuration());
        }
        internal void Cleanup()
        {
            curveEvaluatorOptimizedFloat?.Cleanup();
            curveEvaluatorOptimizedVector3?.Cleanup();
            curveEvaluatorOptimizedQuaternion?.Cleanup();

            Channels.Clear();
            BlenderChannels = null;
            clip = null;
        }
Beispiel #19
0
        public void ItWillNotBeEnabledIfOtherClipsArePlaying()
        {
            string name = "MyClip";
            AnimationClip clip = new AnimationClip();
            animation.AddClip(clip, name);
            animation.Play(name);

            AnimationState state = animation.PlayQueued(name);
            Assert.That(state.enabled, Is.False);
        }
Beispiel #20
0
 public void CheckDefaultValues()
 {
     var animationClip = new AnimationClip<float>();
       Assert.IsNull(animationClip.Traits);
       Assert.IsNull(animationClip.Animation);
       Assert.IsFalse(animationClip.ClipStart.HasValue);
       Assert.IsFalse(animationClip.ClipEnd.HasValue);
       Assert.AreEqual(TimeSpan.FromSeconds(0.0), animationClip.ClipOffset);
       Assert.AreEqual(LoopBehavior.Constant, animationClip.LoopBehavior);
 }
Beispiel #21
0
        public static Node Create(Vector3 pos)
        {
            var cmp = new MyFireExplosion ();

               var spr = new Sprite (100, 100);
               spr.AddTexture (new Texture ("media/FireExplosion.png"));

               var track = new AnimationTrack ("TextureOffset", InterpolationType.Step);
               track.AddKeyframe (0, new Vector2 (0, 0));
               track.AddKeyframe (100, new Vector2 (100, 0));
               track.AddKeyframe (200, new Vector2 (200, 0));
               track.AddKeyframe (300, new Vector2 (300, 0));
               track.AddKeyframe (400, new Vector2 (400, 0));
               track.AddKeyframe (500, new Vector2 (500, 0));
               track.AddKeyframe (600, new Vector2 (600, 0));
               track.AddKeyframe (700, new Vector2 (700, 0));
               track.AddKeyframe (800, new Vector2 (800, 0));
               track.AddKeyframe (900, new Vector2 (900, 0));
               track.AddKeyframe (1000, new Vector2 (0, 100));
               track.AddKeyframe (1100, new Vector2 (100, 100));
               track.AddKeyframe (1200, new Vector2 (200, 100));
               track.AddKeyframe (1300, new Vector2 (300, 100));
               track.AddKeyframe (1400, new Vector2 (400, 100));
               track.AddKeyframe (1500, new Vector2 (500, 100));
               track.AddKeyframe (1600, new Vector2 (600, 100));
               track.AddKeyframe (1700, new Vector2 (700, 100));
               track.AddKeyframe (1800, new Vector2 (800, 100));
               track.AddKeyframe (1900, new Vector2 (900, 100));
               track.AddKeyframe (2000, new Vector2 (0, 200));
               track.AddKeyframe (2100, new Vector2 (100, 200));
               track.AddKeyframe (2200, new Vector2 (200, 200));
               track.AddKeyframe (2300, new Vector2 (300, 200));
               track.AddKeyframe (2400, new Vector2 (400, 200));
               track.AddKeyframe (2500, new Vector2 (500, 200));
               track.AddKeyframe (2600, new Vector2 (600, 200));
               track.AddKeyframe (2700, new Vector2 (700, 200));
               track.AddKeyframe (2800, new Vector2 (800, 200));
               track.AddKeyframe (2900, new Vector2 (900, 200));

               var clip = new AnimationClip (3000, "FireExplosion");
               clip.AddTrack (spr, track);
               clip.WrapMode = WrapMode.Loop;

               var anim = new AnimationController ();
               anim.AddClip (clip);

               var node = new Node ();
               node.Attach (cmp);
               node.Attach (spr);
               node.Attach (anim);

               node.Translation = pos;

               return node;
        }
Beispiel #22
0
    public MixingSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      var modelNode = ContentManager.Load<ModelNode>("Marine/PlayerMarine");
      _meshNode = modelNode.GetSubtree().OfType<MeshNode>().First().Clone();
      SampleHelper.EnablePerPixelLighting(_meshNode);
      GraphicsScreen.Scene.Children.Add(_meshNode);

      var animations = _meshNode.Mesh.Animations;
      _runAnimation = new AnimationClip<SkeletonPose>(animations["Run"])
      {
        LoopBehavior = LoopBehavior.Cycle,
        Duration = TimeSpan.MaxValue,
      };
      _idleAnimation = new AnimationClip<SkeletonPose>(animations["Idle"])
      {
        LoopBehavior = LoopBehavior.Cycle,
        Duration = TimeSpan.MaxValue,
      };

      // Create a 'Shoot' animation that only affects the upper body.
      var shootAnimation = animations["Shoot"];

      // The SkeletonKeyFrameAnimations allows to set a weight for each bone channel. 
      // For the 'Shoot' animation, we set the weight to 0 for all bones that are 
      // not descendants of the second spine bone (bone index 2). That means, the 
      // animation affects only the upper body bones and is disabled on the lower 
      // body bones.
      for (int i = 0; i < _meshNode.Mesh.Skeleton.NumberOfBones; i++)
      {
        if (!SkeletonHelper.IsAncestorOrSelf(_meshNode.SkeletonPose, 2, i))
          shootAnimation.SetWeight(i, 0);
      }

      var loopedShootingAnimation = new AnimationClip<SkeletonPose>(shootAnimation)
      {
        LoopBehavior = LoopBehavior.Cycle,
        Duration = TimeSpan.MaxValue,
      };

      // Start 'Idle' animation.
      _idleAnimationController = AnimationService.StartAnimation(_idleAnimation, (IAnimatableProperty)_meshNode.SkeletonPose);
      _idleAnimationController.AutoRecycle();

      // Start looping the 'Shoot' animation. We use a Compose transition. This will add the 
      // 'Shoot' animation to the animation composition chain and keeping all other playing 
      // animations.
      // The 'Idle' animation animates the whole skeleton. The 'Shoot' animation replaces 
      // the 'Idle' animation on the bones of the upper body.
      AnimationService.StartAnimation(loopedShootingAnimation,
                                      (IAnimatableProperty)_meshNode.SkeletonPose,
                                      AnimationTransitions.Compose()
                                     ).AutoRecycle();
    }
        internal void Cleanup()
        {
            if (curveEvaluatorOptimizedVector3 != null)
                curveEvaluatorOptimizedVector3.Cleanup();
            if (curveEvaluatorOptimizedQuaternion != null)
                curveEvaluatorOptimizedQuaternion.Cleanup();

            Channels.Clear();
            BlenderChannels = null;
            clip = null;
        }
Beispiel #24
0
        public void ItWillBeEnabledImmidiatelyIfNoOtherClipsArePlaying()
        {
            string name = "MyClip";
            AnimationClip clip = new AnimationClip();
            animation.AddClip(clip, name);

            AnimationState state = animation.PlayQueued(name);
            Assert.That(state.enabled, Is.True);
            Assert.That(state.playQueuedReference, Is.True);
            Assert.That(state, Is.Not.SameAs(animation[name]));
            Assert.That(animation[name].playQueuedReference, Is.False);
        }
Beispiel #25
0
        public static Node Create(Vector3 pos)
        {
            var cmp = new MyFireExplosion ();

            var spr = new Sprite (100, 100);
            spr.AddTexture(Resource.GetTexture ("media/FireExplosion.png"));

            var node = new Node ("FireExplosion");
            node.Attach (spr);
            node.Attach (cmp);

            node.Translation = pos - new Vector3(34, 34, 0);   // 爆発の中心を地球にあわせる

            var track = new AnimationTrack ("TextureOffset", InterpolationType.Step);
            track.AddKeyframe (0, new Vector2 (0, 0));
            track.AddKeyframe (100, new Vector2 (100, 0));
            track.AddKeyframe (200, new Vector2 (200, 0));
            track.AddKeyframe (300, new Vector2 (300, 0));
            track.AddKeyframe (400, new Vector2 (400, 0));
            track.AddKeyframe (500, new Vector2 (500, 0));
            track.AddKeyframe (600, new Vector2 (600, 0));
            track.AddKeyframe (700, new Vector2 (700, 0));
            track.AddKeyframe (800, new Vector2 (800, 0));
            track.AddKeyframe (900, new Vector2 (900, 0));
            track.AddKeyframe (1000, new Vector2 (0, 100));
            track.AddKeyframe (1100, new Vector2 (100, 100));
            track.AddKeyframe (1200, new Vector2 (200, 100));
            track.AddKeyframe (1300, new Vector2 (300, 100));
            track.AddKeyframe (1400, new Vector2 (400, 100));
            track.AddKeyframe (1500, new Vector2 (500, 100));
            track.AddKeyframe (1600, new Vector2 (600, 100));
            track.AddKeyframe (1700, new Vector2 (700, 100));
            track.AddKeyframe (1800, new Vector2 (800, 100));
            track.AddKeyframe (1900, new Vector2 (900, 100));
            track.AddKeyframe (2000, new Vector2 (0, 200));
            track.AddKeyframe (2100, new Vector2 (100, 200));
            track.AddKeyframe (2200, new Vector2 (200, 200));
            track.AddKeyframe (2300, new Vector2 (300, 200));
            track.AddKeyframe (2400, new Vector2 (400, 200));
            track.AddKeyframe (2500, new Vector2 (500, 200));
            track.AddKeyframe (2600, new Vector2 (600, 200));
            track.AddKeyframe (2700, new Vector2 (700, 200));
            track.AddKeyframe (2800, new Vector2 (800, 200));
            track.AddKeyframe (2900, new Vector2 (900, 200));

            var clip = new AnimationClip (3000, "Explosion");
            clip.AddTrack (spr, track);
            clip.WrapMode = WrapMode.Once;

            node.UserData.Add (clip.Name, clip);

            return node;
        }
Beispiel #26
0
        public void Test_New()
        {
            var clip = new AnimationClip (100, "ClipName");

            Assert.AreEqual (100, clip.Duration);
            Assert.AreEqual ("ClipName", clip.Name);
            Assert.AreEqual (1, clip.Speed);
            Assert.AreEqual (WrapMode.Loop, clip.WrapMode);
            Assert.AreEqual (false, clip.IsPlaying);
            Assert.AreEqual (0, clip.TrackCount);
            Assert.AreEqual (0, clip.EventCount);
        }
Beispiel #27
0
    public CollisionDetectionOnlyRagdollSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      GraphicsScreen.DrawReticle = true;
      SetCamera(new Vector3F(0, 1, 6), 0, 0);

      // Add a game object which allows to shoot balls.
      _ballShooterObject = new BallShooterObject(Services);
      GameObjectService.Objects.Add(_ballShooterObject);

      var modelNode = ContentManager.Load<ModelNode>("Dude/Dude");
      _meshNode = modelNode.GetSubtree().OfType<MeshNode>().First().Clone();
      _meshNode.PoseLocal = new Pose(new Vector3F(0, 0, 0), Matrix33F.CreateRotationY(ConstantsF.Pi));
      SampleHelper.EnablePerPixelLighting(_meshNode);
      GraphicsScreen.Scene.Children.Add(_meshNode);

      var animations = _meshNode.Mesh.Animations;
      var loopingAnimation = new AnimationClip<SkeletonPose>(animations.Values.First())
      {
        LoopBehavior = LoopBehavior.Cycle,
        Duration = TimeSpan.MaxValue,
      };
      AnimationService.StartAnimation(loopingAnimation, (IAnimatableProperty)_meshNode.SkeletonPose);

      // Create a ragdoll for the Dude model.
      _ragdoll = new Ragdoll();
      DudeRagdollCreator.Create(_meshNode.SkeletonPose, _ragdoll, Simulation, 0.571f);

      // Set the world space pose of the whole ragdoll. 
      _ragdoll.Pose = _meshNode.PoseWorld;
      // And copy the bone poses of the current skeleton pose.
      _ragdoll.UpdateBodiesFromSkeleton(_meshNode.SkeletonPose);

      foreach (var body in _ragdoll.Bodies)
      {
        if (body != null)
        {
          // Set all bodies to kinematic - they should not be affected by forces.
          body.MotionType = MotionType.Kinematic;

          // Disable collision response.
          body.CollisionResponseEnabled = false;
        }
      }

      // In this sample, we do not need joints, limits or motors.
      _ragdoll.DisableJoints();
      _ragdoll.DisableLimits();
      _ragdoll.DisableMotors();

      // Add ragdoll rigid bodies to the simulation.
      _ragdoll.AddToSimulation(Simulation);
    }
Beispiel #28
0
        public void GetValueTest()
        {
            var animation = new AnimationClip<float>
              {
            Animation = new SingleFromToByAnimation
            {
              From = 100,
              To = 200,
              Duration = TimeSpan.FromSeconds(6.0),
            },
            Delay = TimeSpan.FromSeconds(10),
            Speed = 2,
            FillBehavior = FillBehavior.Hold,
              };

              var animation2 = new AnimationClip<float>
              {
            Animation = new SingleFromToByAnimation
            {
              From = 10,
              To = 20,
              Duration = TimeSpan.FromSeconds(5.0),
            },
            Delay = TimeSpan.Zero,
            Speed = 1,
            FillBehavior = FillBehavior.Hold,
              };

              var animationEx = new Vector2FAnimation
              {
            X = animation,
            Y = animation2,
              };

              var defaultSource = new Vector2F(1, 2);
              var defaultTarget = new Vector2F(5, 6);

              var result = animationEx.GetValue(TimeSpan.FromSeconds(0.0), defaultSource, defaultTarget);
              Assert.AreEqual(defaultSource.X, result.X); // animation has not started.
              Assert.AreEqual(10.0f, result.Y);           // animation2 has started.

              result = animationEx.GetValue(TimeSpan.FromSeconds(5.0), defaultSource, defaultTarget);
              Assert.AreEqual(defaultSource.X, result.X); // animation has not started.
              Assert.AreEqual(20.0f, result.Y);           // animation2 has ended.

              result = animationEx.GetValue(TimeSpan.FromSeconds(5.0), defaultSource, defaultTarget);
              Assert.AreEqual(defaultSource.X, result.X); // animation has not started.
              Assert.AreEqual(20.0f, result.Y);           // animation2 has ended.

              result = animationEx.GetValue(TimeSpan.FromSeconds(13.0), defaultSource, defaultTarget);
              Assert.AreEqual(200, result.X);             // animation has ended.
              Assert.AreEqual(20.0f, result.Y);           // animation2 is filling.
        }
Beispiel #29
0
        public void GetTotalDurationTest()
        {
            var animationClip = new AnimationClip<float>();
              Assert.AreEqual(TimeSpan.FromSeconds(0.0), animationClip.GetTotalDuration());

              animationClip.Animation = new AnimationClip<float>
              {
            Animation = new SingleFromToByAnimation(),
            Delay = TimeSpan.FromSeconds(10),
            Duration = TimeSpan.FromSeconds(4.0),
            Speed = 2.0f,
              };
              Assert.AreEqual(TimeSpan.FromSeconds(12.0), animationClip.GetTotalDuration());
        }
Beispiel #30
0
    public CrossFadeSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      Rectangle bounds = GraphicsService.GraphicsDevice.Viewport.TitleSafeArea;

      // Set the base value of the _animatedPosition. When the animations are stopped,
      // _animatedPosition will return to this value.
      _animatedPosition.Value = new Vector2(bounds.Center.X, bounds.Center.Y);

      // Create an oscillating horizontal animation.
      Vector2FromToByAnimation fromToAnimation = new Vector2FromToByAnimation
      {
        From = new Vector2(200, bounds.Center.Y),
        To = new Vector2(bounds.Right - 200, bounds.Center.Y),
        Duration = TimeSpan.FromSeconds(2),
        EasingFunction = new CubicEase { Mode = EasingMode.EaseInOut },
      };

      _horizontalAnimation = new AnimationClip<Vector2>(fromToAnimation)
      {
        LoopBehavior = LoopBehavior.Oscillate,
        Duration = TimeSpan.MaxValue,
      };

      // Create an oscillating vertical animation.
      fromToAnimation = new Vector2FromToByAnimation
      {
        From = new Vector2(bounds.Center.X, 100),
        To = new Vector2(bounds.Center.X, bounds.Bottom - 100),
        Duration = TimeSpan.FromSeconds(2),
        EasingFunction = new CubicEase { Mode = EasingMode.EaseInOut },
      };

      _verticalAnimation = new AnimationClip<Vector2>(fromToAnimation)
      {
        LoopBehavior = LoopBehavior.Oscillate,
        Duration = TimeSpan.MaxValue,
      };

      // Start the horizontal movement. AnimationService.StartAnimation() returns an
      // AnimationController. We keep this AnimationController because it is needed to fade-out
      // the animation.
      _state = 1;
      _currentAnimationController = AnimationService.StartAnimation(_horizontalAnimation, _animatedPosition);
      _currentAnimationController.UpdateAndApply();

      // When the animation is stopped, all intermediate animation objects should be recycled.
      _currentAnimationController.AutoRecycle();
    }
 public static extern void SetAnimationEvents(AnimationClip clip, AnimationEvent[] events);
 public static void SetAnimationType(AnimationClip clip, ModelImporterAnimationType type)
 {
 }
 internal static extern void SetGenerateMotionCurves(AnimationClip clip, bool value);
 public static extern AnimationClipSettings GetAnimationClipSettings(AnimationClip clip);
 public static extern AnimationEvent[] GetAnimationEvents(AnimationClip clip);
 public static extern AnimationCurve GetEditorCurve(AnimationClip clip, EditorCurveBinding binding);
 internal static extern bool GetGenerateMotionCurves(AnimationClip clip);
Beispiel #38
0
        //GameObject o = null;
        void OnGUI()
        {
            if (_labelstyle == null)
            {
                _labelstyle          = new GUIStyle(EditorStyles.boldLabel);
                _labelstyle.fontSize = 11;
            }

            scrollPosition = GUILayout.BeginScrollView(scrollPosition, false, false);
            EditorGUILayout.Space();
            GUILayout.Label("CutScene Editor:", _labelstyle);
            EditorGUILayout.Space();
            _name = EditorGUILayout.TextField("Name", _name);
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Scene", _scene);
            if (GUILayout.Button("Browser", GUILayout.MaxWidth(80)))
            {
                string file = EditorUtility.OpenFilePanel("Select unity scene file", XEditorLibrary.Sce, "unity");

                if (file.Length != 0)
                {
                    file   = file.Remove(file.LastIndexOf("."));
                    _scene = file.Remove(0, file.IndexOf(XEditorLibrary.Sce));

                    Scene scene = EditorSceneManager.GetActiveScene();
                    if (scene.name.Length == 0 || !EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
                    {
                        EditorSceneManager.OpenScene(_scene + ".unity");
                    }
                }
            }
            EditorGUILayout.EndHorizontal();
            _auto_end = EditorGUILayout.Toggle("Auto End", _auto_end);
            EditorGUILayout.Space();
            _general_show = EditorGUILayout.Toggle("General Clip", _general_show);
            if (_general_show)
            {
                _general_bigguy = EditorGUILayout.Toggle("General Big Guy", _general_bigguy);

                if (_general_bigguy)
                {
                    _camera = Resources.Load("Animation/Main_Camera/Cut_Scene/cutscene_generalshow_bigguy", typeof(AnimationClip)) as AnimationClip;
                }
                else
                {
                    _camera = Resources.Load("Animation/Main_Camera/Cut_Scene/cutscene_generalshow", typeof(AnimationClip)) as AnimationClip;
                }

                EditorGUILayout.ObjectField("Camera Clip", _camera, typeof(AnimationClip), true);
            }
            else
            {
                _camera = EditorGUILayout.ObjectField("Camera Clip", _camera, typeof(AnimationClip), true) as AnimationClip;
            }
            if (_camera != null)
            {
                _length = _camera.length;
                EditorGUILayout.LabelField("CutScene Length", _length.ToString("F3") + "s" + "\t" + (_length * XEditorLibrary.FPS).ToString("F1") + "(frame)");
            }

            EditorGUILayout.Space();
            _type_mask      = (int)(EntitySpecies)EditorGUILayout.EnumMaskField("Type Mask", (EntitySpecies)_type_mask);
            _mourningborder = EditorGUILayout.Toggle("Mourningborder", _mourningborder);

            EditorGUILayout.Space();
            _fov     = EditorGUILayout.FloatField("FieldOfVeiw", _fov);
            _trigger = (CameraTrigger)EditorGUILayout.EnumPopup("Trigger", _trigger);
            EditorGUILayout.Space();
            _override_bgm = EditorGUILayout.Toggle("Override BGM", _override_bgm);
            EditorGUILayout.Space();

            UpdateScript();

            GUILayout.Label("TimeLine:", _labelstyle);
            EditorGUILayout.Space();
            EditorGUILayout.BeginHorizontal();
            _type = (XClipType)EditorGUILayout.EnumPopup("Add Clip", _type);
            if (GUILayout.Button(_content_add, GUILayout.MaxWidth(25), GUILayout.MaxHeight(15)))
            {
                if (_camera != null && _name != null && _name.Length > 0)
                {
                    XCutSceneTimelineWindow window = EditorWindow.GetWindow <XCutSceneTimelineWindow>(@"Timeline At:");
                    window._total_frame = _camera.length * XEditorLibrary.FPS;
                    window._clip        = null;
                }
                else
                {
                    EditorUtility.DisplayDialog("Confirm your selection.",
                                                "Please select camera clip or name the cutscene",
                                                "Ok");
                }
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.Space();
            ActorList.Clear();
            ActorList.Add("None");

            foreach (XClip clip in _clips.Values)
            {
                if (clip.Valid)
                {
                    if (_camera != null)
                    {
                        clip.TimeLineTotal = _camera.length * XEditorLibrary.FPS;
                        clip.OnGUI(GetCurrentData());

                        if (clip.ClipType == XClipType.Actor || clip.ClipType == XClipType.Player)
                        {
                            int all = ActorList.FindAll(s => s == clip.Name).Count;
                            if (all > 0)
                            {
                                ActorList.Add(clip.Name + " " + (all + 1));
                            }
                            else
                            {
                                ActorList.Add(clip.Name);
                            }
                        }
                    }
                }
            }

            EditorGUILayout.Space();
            EditorGUILayout.Space();
            EditorGUILayout.Space();

            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("Run"))
            {
                if (_name != null && _name.Length > 0 && _camera != null && !EditorApplication.isPlaying)
                {
                    EditorApplication.ExecuteMenuItem("Edit/Play");
                    GameObject   _cameraObject = GameObject.Find(@"Main Camera");
                    GameEntrance entrance      = _cameraObject.GetComponent <GameEntrance>();
                    entrance.enabled = false;
                    XCutSceneRunner runner = _cameraObject.AddComponent <XCutSceneRunner>();
                    _run_data = GetCurrentData();
                    runner.is_start_by_editor = true;
                    runner.cut_scene_data     = _run_data;
                }
            }
            if (GUILayout.Button("Pause"))
            {
                if (EditorApplication.isPlaying)
                {
                    EditorApplication.isPaused = !EditorApplication.isPaused;
                }
            }

            if (GUILayout.Button("Quit"))
            {
                if (EditorApplication.isPlaying)
                {
                    EditorApplication.isPlaying = false;
                }
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Space();
            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("Save"))
            {
                Save();
            }

            if (GUILayout.Button("Open"))
            {
                _file = EditorUtility.OpenFilePanel("Select cutscene file", XEditorLibrary.Cts, "txt");
                if (_file.Length != 0)
                {
                    _open_scene = true;
                    Load(XDataIO <XCutSceneData> .singleton.DeserializeData(_file.Substring(_file.IndexOf("Assets/"))));
                }
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndScrollView();
        }
Beispiel #39
0
        void InnerLoad(XCutSceneData data)
        {
            _run_data = data;

            _name           = data.Name;
            _script         = data.Script;
            _scene          = data.Scene;
            _camera         = Resources.Load(data.CameraClip, typeof(AnimationClip)) as AnimationClip;
            _type_mask      = data.TypeMask;
            _auto_end       = data.AutoEnd;
            _general_show   = data.GeneralShow;
            _general_bigguy = data.GeneralBigGuy;
            _override_bgm   = data.OverrideBGM;
            _mourningborder = data.Mourningborder;
            _fov            = data.FieldOfView;
            _length         = data.Length;
            _trigger        = (CameraTrigger)Enum.Parse(typeof(CameraTrigger), data.Trigger);

            _clips.Clear();
            ActorList.Clear();
            ActorList.Add("None");
            foreach (XActorDataClip clip in data.Actors)
            {
                TimeChecker(clip, data);
                XClip xclip = AddClip(clip);
                ActorList.Add(xclip.Name);
            }
            foreach (XPlayerDataClip clip in data.Player)
            {
                TimeChecker(clip, data);
                XClip xclip = AddClip(clip);
                ActorList.Add(xclip.Name);
            }
            foreach (XFxDataClip clip in data.Fxs)
            {
                TimeChecker(clip, data);
                AddClip(clip);
            }
            foreach (XAudioDataClip clip in data.Audios)
            {
                TimeChecker(clip, data);
                AddClip(clip);
            }
            foreach (XSubTitleDataClip clip in data.SubTitle)
            {
                TimeChecker(clip, data);
                AddClip(clip);
            }
            foreach (XSlashDataClip clip in data.Slash)
            {
                TimeChecker(clip, data);
                AddClip(clip);
            }

            if (_open_scene && _scene != null && _scene.Length != 0)
            {
                Scene scene = EditorSceneManager.GetActiveScene();
                if (scene.name.Length > 0 && !EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
                {
                    return;
                }
                else
                {
                    EditorSceneManager.OpenScene(_scene + ".unity");
                }
                _open_scene = false;
            }
        }
Beispiel #40
0
    void DrawAnimation()
    {
        if (mData.AnimationSkillList == null)
        {
            return;
        }

        for (int i = 0; i < mData.AnimationSkillList.Count; i++)
        {
            EditorGUILayout.Space();

            AnimationSkillStruct _ass = mData.AnimationSkillList[i];

            if (_ass.IsFoldout)
            {
                EditorGUILayout.BeginVertical(EditorStyles.helpBox);

                EditorGUILayout.LabelField(_ass.Type.ToString());
                if (GUILayout.Button("Preview"))
                {
                    mASD.PlayAnimaState(_ass.Type);
                }

                _ass.AnimationClip = (AnimationClip)EditorGUILayout.ObjectField("AnimaitonClip:", _ass.AnimationClip, typeof(AnimationClip), true);

                EditorGUILayout.BeginHorizontal();
                if (_ass.AnimationClip == null)
                {
                    _ass.fTime = 1f;
                }
                else
                {
                    _ass.fTime = _ass.AnimationClip.length;
                }
                EditorGUILayout.LabelField("NextAnima After:", _ass.fTime.ToString());
                _ass.NextType = (NFAnimaStateType)EditorGUILayout.EnumPopup(_ass.NextType);

                EditorGUILayout.EndHorizontal();

                AnimatorController ctl = (AnimatorController)mASD.GetComponent <Animator> ().runtimeAnimatorController;
                if (ctl != null)
                {
                    AnimatorStateMachine state_machine = ctl.layers[0].stateMachine;
                    for (int j = 0; j < state_machine.states.Length; ++j)
                    {
                        if (state_machine.states [j].state.name == _ass.Type.ToString())
                        {
                            String        strPath = AssetDatabase.GetAssetPath(_ass.AnimationClip);
                            AnimationClip anim    = AssetDatabase.LoadAssetAtPath(strPath, typeof(AnimationClip)) as AnimationClip;
                            state_machine.states [j].state.motion = anim;
                            break;
                        }
                    }
                }

                mData.AnimationSkillList[i] = _ass;

                //添加特效与删除片断
                EditorGUILayout.BeginHorizontal();
                if (GUILayout.Button("ADD EFFECT"))
                {
                    EffectStruct _es = new EffectStruct();
                    _es.LifeTime  = 3;
                    _es.isFoldout = true;
                    mData.AnimationSkillList[i].EffectStructList.Add(_es);
                }
                if (GUILayout.Button("ADD Audio"))
                {
                    AudioStruct _es = new AudioStruct();
                    _es.LifeTime  = 3;
                    _es.isFoldout = true;
                    mData.AnimationSkillList[i].AudioStructList.Add(_es);
                }
                if (GUILayout.Button("ADD Bullet"))
                {
                    BulletStruct _es = new BulletStruct();
                    _es.isFoldout = true;
                    mData.AnimationSkillList[i].BulletStructList.Add(_es);
                }



                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                if (GUILayout.Button("ADD Damage"))
                {
                    DamageStruct _es = new DamageStruct();
                    _es.isFoldout = true;
                    mData.AnimationSkillList[i].DamageStructList.Add(_es);
                }

                if (GUILayout.Button("ADD Movement"))
                {
                    MovementStruct _es = new MovementStruct();
                    _es.isFoldout = true;
                    mData.AnimationSkillList[i].MovementStructList.Add(_es);
                }

                if (GUILayout.Button("ADD Camera"))
                {
                    CameraStruct _es = new CameraStruct();
                    _es.isFoldout = true;
                    mData.AnimationSkillList[i].CameraStructList.Add(_es);
                }

                EditorGUILayout.EndHorizontal();

                if (mData.AnimationSkillList.Count > 0)
                {
                    DrawEffect(i);
                    DrawAudio(i);
                    DrawMovement(i);
                    DrawDamage(i);
                    DrawBullet(i);
                    DrawCamera(i);
                }
                EditorGUILayout.EndVertical();
            }
        }
    }
Beispiel #41
0
    /// <summary>
    /// 替换动画控制器中使用的Clip
    /// </summary>
    public static void replaceStateMotion(AnimatorController ctrl, AnimationClip oldClip, AnimationClip newClip, bool replaceAll = false)
    {
        var e = ctrl.layers.GetEnumerator();

        while (e.MoveNext())
        {
            AnimatorControllerLayer layer = (AnimatorControllerLayer)e.Current;
            var child = layer.stateMachine.states.GetEnumerator();
            while (child.MoveNext())
            {
                ChildAnimatorState childState = (ChildAnimatorState)child.Current;
                if (childState.state.motion == oldClip)
                {
                    ctrl.SetStateEffectiveMotion(childState.state, newClip);
                    if (!replaceAll)
                    {
                        return;
                    }
                }
            }
        }
    }
Beispiel #42
0
 public bool RemoveClip(AnimationClip clip)
 {
     InvalidateStates();
     return(m_States.RemoveClip(clip));
 }
 public static void SaveAnimationClip(AnimationClip clip, string path)
 {
     AssetDatabase.CreateAsset(clip, path);
     AssetDatabase.SaveAssets();
     AssetDatabase.Refresh();
 }
    public static void SetClipToAnimatorControllerState(AnimationClip clip, string controllerPath, int layerIdx, string stateName)
    {
        var animatorState = GetAnimatorState(controllerPath, stateName, layerIdx);

        animatorState.motion = clip;
    }
        private static bool GetEditableClip(IEnumerable <TimelineClip> clips, out TimelineClip clip, out AnimationClip animClip)
        {
            clip     = null;
            animClip = null;

            if (clips.Count() != 1)
            {
                return(false);
            }

            clip = clips.FirstOrDefault();
            if (clip == null)
            {
                return(false);
            }

            if (clip.animationClip != null)
            {
                animClip = clip.animationClip;
            }
            else if (clip.curves != null && !clip.curves.empty)
            {
                animClip = clip.curves;
            }

            return(animClip != null);
        }
Beispiel #46
0
            /// <summary>
            /// Generates a clip from this SpriteAnim
            /// </summary>
            /// <param name="savePath">Save path.</param>
            /// <param name="filenamePrefix">Filename prefix.</param>
            public void GenerateClip(string savePath, string filenamePrefix)
            {
                // Output nothing if there is no clip name
                if (string.IsNullOrEmpty(this.clipName))
                {
                    return;
                }

                // Output nothing if no frames are defined
                if (this.animationKeyframes == null || this.animationKeyframes.Length == 0)
                {
                    return;
                }

                // Get the clip to add our Sprite Animation into, or create a new one.
                AnimationClip builtClip;
                bool          clipIsNew;

                if (this.savedClip == null)
                {
                    builtClip = new AnimationClip();
                    clipIsNew = true;
                }
                else
                {
                    builtClip = this.savedClip;
                    clipIsNew = false;
                }

                builtClip.name      = this.clipName;
                builtClip.frameRate = this.Samples;

                // Set the Looping status of the clip
                AnimationClipSettings clipSettings = new AnimationClipSettings();

                clipSettings.loopTime = this.isLooping;
                AnimationUtility.SetAnimationClipSettings(builtClip, clipSettings);

                // Clear ALL existing sprite bindings in the clip
                EditorCurveBinding[] existingObjectBinding = AnimationUtility.GetObjectReferenceCurveBindings(builtClip);
                for (int i = 0; i < existingObjectBinding.Length; i++)
                {
                    EditorCurveBinding currentBinding = existingObjectBinding[i];
                    if (currentBinding.type == typeof(SpriteRenderer))
                    {
                        AnimationUtility.SetObjectReferenceCurve(builtClip, currentBinding, null);
                    }
                }

                // Clear existing Scale since it will be replaced
                EditorCurveBinding[] existingValueBindings = AnimationUtility.GetCurveBindings(builtClip);
                for (int i = 0; i < existingValueBindings.Length; i++)
                {
                    EditorCurveBinding currentBinding = existingValueBindings[i];
                    if (currentBinding.type == typeof(Transform) && currentBinding.propertyName == "m_LocalScale.x")
                    {
                        builtClip.SetCurve(currentBinding.path, typeof(Transform), "m_LocalScale", null);
                        break;
                    }
                }

                // Initialize the curve property
                EditorCurveBinding curveBinding = new EditorCurveBinding();

                curveBinding.propertyName = "m_Sprite";
                curveBinding.path         = this.PathToSpriteRenderer;
                curveBinding.type         = typeof(SpriteRenderer);

                // Build keyframes for the property
                Sprite[] sprites = AssetDatabaseUtility.LoadSpritesInTextureSorted(this.SourceTexture);
                ObjectReferenceKeyframe[] keys = this.CreateKeysForKeyframeRanges(sprites, this.animationKeyframes, this.Samples);

                // Build the clip if valid
                if (keys != null && keys.Length > 0)
                {
                    // Set the keyframes to the animation
                    AnimationUtility.SetObjectReferenceCurve(builtClip, curveBinding, keys);

                    // Add scaling to mirror sprites
                    // Need to also restore scale in case a clip was previously mirrored and then unflagged
                    AnimationCurve normalCurve = AnimationCurve.Linear(0.0f, 1.0f, builtClip.length, 1.0f);
                    AnimationCurve mirrorCurve = AnimationCurve.Linear(0.0f, -1.0f, builtClip.length, -1.0f);
                    AnimationCurve xCurve      = this.isMirroredX ? mirrorCurve : normalCurve;
                    AnimationCurve yCurve      = this.isMirroredY ? mirrorCurve : normalCurve;
                    builtClip.SetCurve(this.PathToSpriteRenderer, typeof(Transform), "localScale.x", xCurve);
                    builtClip.SetCurve(this.PathToSpriteRenderer, typeof(Transform), "localScale.y", yCurve);
                    builtClip.SetCurve(this.PathToSpriteRenderer, typeof(Transform), "localScale.z", normalCurve);

                    // Create or replace the file
                    string filenameSansExtension = filenamePrefix + "_" + this.clipName;
                    if (clipIsNew)
                    {
                        string filename = filenameSansExtension + ".anim";
                        string fullpath = savePath + filename;
                        AssetDatabase.CreateAsset(builtClip, fullpath);
                    }
                    else
                    {
                        string pathToAsset = AssetDatabase.GetAssetPath(this.savedClip);

                        // renaming file doesn't expect extension for some reason
                        AssetDatabase.RenameAsset(pathToAsset, filenameSansExtension);
                    }

                    // Store reference to created clip to allow overwriting / renaming
                    this.savedClip = builtClip;
                }
                else
                {
                    if (keys == null)
                    {
                        Debug.LogWarning("Skipping clip due to no keys found: " + this.clipName);
                    }
                    else
                    {
                        Debug.LogWarning("Encountered invalid clip. Not enough keys. Skipping clip: " + this.clipName);
                    }
                }
            }
 public static AnimationCurve GetEditorCurve(AnimationClip clip, string relativePath, Type type, string propertyName)
 {
     return(GetEditorCurve(clip, EditorCurveBinding.FloatCurve(relativePath, type, propertyName)));
 }
        static BlobAssetReference <CurvesInfo> ConvertFloatCurves([NotNull] AnimationClip clip)
        {
            var bindings = AnimationUtility
                           .GetCurveBindings(clip)
                           .OrderBy(b => b.path)        // Ensures we are processing one target at a time
                           .ThenBy(b => b.propertyName) // Ensures we are processing vector properties together
                           .ToArray();

            var numBindings = bindings.Length;

            var blobAssetRef = BlobAssetReference <CurvesInfo> .Null;

            if (numBindings == 0)
            {
                return(blobAssetRef);
            }

            var targetPaths = new List <FixedString512>(numBindings);
            var animationBindingsConvertedNames = new List <FixedString512>(numBindings);
            var keyframeCurves = new List <KeyframeCurve>(numBindings);

            var scaleRequired = false;
            var numKeys       = 0;
            var numBindingsAfterConversion = numBindings;

            for (var i = 0; i < numBindings; i++)
            {
                var binding      = bindings[i];
                var rotationMode = TinyAnimationEditorBridge.GetRotationMode(binding);

                // Handle non quaternion rotation.
                if (rotationMode != TinyAnimationEditorBridge.RotationMode.Undefined && rotationMode != TinyAnimationEditorBridge.RotationMode.RawQuaternions)
                {
                    // TODO: Handle other modes when/if they show up
                    if (rotationMode == TinyAnimationEditorBridge.RotationMode.RawEuler)
                    {
                        var currentPath = binding.path;

                        var xBinding = default(EditorCurveBinding);
                        var yBinding = default(EditorCurveBinding);
                        var zBinding = default(EditorCurveBinding);

                        var rotationBindingOffset = 0;
                        while (rotationBindingOffset < 3 && i + rotationBindingOffset < numBindings)
                        {
                            var nextBinding = bindings[i + rotationBindingOffset];
                            if (!string.Equals(currentPath, nextBinding.path, StringComparison.Ordinal) || TinyAnimationEditorBridge.GetRotationMode(nextBinding) != TinyAnimationEditorBridge.RotationMode.RawEuler)
                            {
                                // Binding is either for a different target or not a rotation: skip!
                                break;
                            }

                            if (nextBinding.propertyName.EndsWith(".x", StringComparison.Ordinal))
                            {
                                xBinding = nextBinding;
                            }
                            else if (nextBinding.propertyName.EndsWith(".y", StringComparison.Ordinal))
                            {
                                yBinding = nextBinding;
                            }
                            else
                            {
                                zBinding = nextBinding;
                            }

                            rotationBindingOffset++;
                        }

                        var xCurveOriginal = xBinding != default
                            ? AnimationUtility.GetEditorCurve(clip, xBinding)
                            : new AnimationCurve(new UnityEngine.Keyframe(0.0f, 0.0f), new UnityEngine.Keyframe(clip.length, 0.0f));

                        var yCurveOriginal = yBinding != default
                            ? AnimationUtility.GetEditorCurve(clip, yBinding)
                            : new AnimationCurve(new UnityEngine.Keyframe(0.0f, 0.0f), new UnityEngine.Keyframe(clip.length, 0.0f));

                        var zCurveOriginal = zBinding != default
                            ? AnimationUtility.GetEditorCurve(clip, zBinding)
                            : new AnimationCurve(new UnityEngine.Keyframe(0.0f, 0.0f), new UnityEngine.Keyframe(clip.length, 0.0f));

                        var xCurveNew = new AnimationCurve();
                        var yCurveNew = new AnimationCurve();
                        var zCurveNew = new AnimationCurve();
                        var wCurveNew = new AnimationCurve();

                        // We *need* to resample at the framerate when converting from Euler to Quaternion
                        var step = clip.length / clip.frameRate;
                        var time = 0.0f;
                        do
                        {
                            EvaluateAndConvert(time);
                            time += step;
                        }while (time <= clip.length - step);

                        // Setting the last frame explicitly to avoid precision errors
                        EvaluateAndConvert(clip.length);

                        void EvaluateAndConvert(float t)
                        {
                            var euler = new float3(xCurveOriginal.Evaluate(t), yCurveOriginal.Evaluate(t), zCurveOriginal.Evaluate(t));
                            var quat  = quaternion.Euler(math.radians(euler));

                            xCurveNew.AddKey(new UnityEngine.Keyframe(t, quat.value.x, Mathf.Infinity, Mathf.Infinity));
                            yCurveNew.AddKey(new UnityEngine.Keyframe(t, quat.value.y, Mathf.Infinity, Mathf.Infinity));
                            zCurveNew.AddKey(new UnityEngine.Keyframe(t, quat.value.z, Mathf.Infinity, Mathf.Infinity));
                            wCurveNew.AddKey(new UnityEngine.Keyframe(t, quat.value.w, Mathf.Infinity, Mathf.Infinity));
                        }

                        var resampledKeysCount = xCurveNew.length;

                        var xPropName = GetConvertedName(binding.type, TinyAnimationEditorBridge.CreateRawQuaternionsBindingName("x"));
                        var yPropName = GetConvertedName(binding.type, TinyAnimationEditorBridge.CreateRawQuaternionsBindingName("y"));
                        var zPropName = GetConvertedName(binding.type, TinyAnimationEditorBridge.CreateRawQuaternionsBindingName("z"));
                        var wPropName = GetConvertedName(binding.type, TinyAnimationEditorBridge.CreateRawQuaternionsBindingName("w"));

                        animationBindingsConvertedNames.Add(new FixedString512(xPropName));
                        animationBindingsConvertedNames.Add(new FixedString512(yPropName));
                        animationBindingsConvertedNames.Add(new FixedString512(zPropName));
                        animationBindingsConvertedNames.Add(new FixedString512(wPropName));

                        keyframeCurves.Add(xCurveNew.ToKeyframeCurve());
                        keyframeCurves.Add(yCurveNew.ToKeyframeCurve());
                        keyframeCurves.Add(zCurveNew.ToKeyframeCurve());
                        keyframeCurves.Add(wCurveNew.ToKeyframeCurve());

                        numKeys += resampledKeysCount * 4;

                        var targetPath = string.IsNullOrEmpty(binding.path) ? string.Empty : binding.path;
                        targetPaths.Add(targetPath);
                        targetPaths.Add(targetPath);
                        targetPaths.Add(targetPath);
                        targetPaths.Add(targetPath);

                        // How many new bindings were added by this conversion?
                        // e.g.:
                        //     Euler bindings to [x,y,z] converts to quaternion bindings [x,y,z,w], so we added 1 new binding
                        //     Euler bindings to [y] converts to  quaternion bindings [x,y,z,w], so we added 3 new binding
                        numBindingsAfterConversion += 4 - rotationBindingOffset;

                        // Skip already processed bindings
                        i += rotationBindingOffset - 1;
                    }
                    else
                    {
                        throw new InvalidOperationException($"Rotation mode: {rotationMode} is not supported.");
                    }
                }
                else
                {
                    // Note: Empty string maps to self in Transform.Find()
                    targetPaths.Add(string.IsNullOrEmpty(binding.path) ? string.Empty : binding.path);

                    var bindingPropertyName = binding.propertyName;
                    var convertedName       = GetConvertedName(binding.type, bindingPropertyName);

                    animationBindingsConvertedNames.Add(new FixedString512(convertedName));

                    var animationCurve = AnimationUtility.GetEditorCurve(clip, binding);
                    var curve          = animationCurve.ToKeyframeCurve();
                    keyframeCurves.Add(curve);
                    numKeys += curve.Length;

                    if (!scaleRequired && binding.type == typeof(Transform) && bindingPropertyName.StartsWith("m_LocalScale.", StringComparison.Ordinal))
                    {
                        scaleRequired = true;
                    }
                }
            }

            using (var blobBuilder = new BlobBuilder(Allocator.Temp))
            {
                ref var builderRoot = ref blobBuilder.ConstructRoot <CurvesInfo>();

                var keyframesBuilder    = blobBuilder.Allocate(ref builderRoot.Keyframes, numKeys);
                var curveOffsetsBuilder = blobBuilder.Allocate(ref builderRoot.CurveOffsets, numBindingsAfterConversion);
                var bindingNamesBuilder = blobBuilder.Allocate(ref builderRoot.BindingNames, numBindingsAfterConversion);
                var targetPathsBuilder  = blobBuilder.Allocate(ref builderRoot.TargetGameObjectPaths, numBindingsAfterConversion);

                // We don't care about that field in this case
                blobBuilder.Allocate(ref builderRoot.AnimatedAssetGroupings, 0);

                for (int bindingIndex = 0, keyIndex = 0, curveOffset = 0; bindingIndex < numBindingsAfterConversion; ++bindingIndex)
                {
                    var keyframeCurve = keyframeCurves[bindingIndex];
                    for (var i = 0; i < keyframeCurve.Length; ++i)
                    {
                        keyframesBuilder[keyIndex++] = keyframeCurve[i];
                    }

                    curveOffsetsBuilder[bindingIndex] = curveOffset;
                    curveOffset += keyframeCurve.Length;
                    bindingNamesBuilder[bindingIndex] = animationBindingsConvertedNames[bindingIndex];
                    targetPathsBuilder[bindingIndex]  = targetPaths[bindingIndex];
                }

                builderRoot.ConversionActions = scaleRequired ? RequiredConversionActions.PatchScale : RequiredConversionActions.None;

                blobAssetRef = blobBuilder.CreateBlobAssetReference <CurvesInfo>(Allocator.Persistent);
            }
 public static extern EditorCurveBinding[] GetCurveBindings(AnimationClip clip);
    void ProcessClipPosition(AnimationClip clip, string objectPathName)
    {
        // Access the position curves for the given object

        EditorCurveBinding bindX = EditorCurveBinding.FloatCurve(objectPathName, typeof(Transform), "m_LocalPosition.x");
        EditorCurveBinding bindY = EditorCurveBinding.FloatCurve(objectPathName, typeof(Transform), "m_LocalPosition.y");
        EditorCurveBinding bindZ = EditorCurveBinding.FloatCurve(objectPathName, typeof(Transform), "m_LocalPosition.z");

        AnimationCurve curveX = AnimationUtility.GetEditorCurve(clip, bindX);
        AnimationCurve curveY = AnimationUtility.GetEditorCurve(clip, bindY);
        AnimationCurve curveZ = AnimationUtility.GetEditorCurve(clip, bindZ);

        if (curveX == null || curveY == null || curveZ == null)
        {
            LogInfo("WARNING: animated object [" + objectPathName + "] doesn't have correct position curves");
            return;
        }

        int keyframes = curveX.length;

        if (curveY.length != keyframes || curveZ.length != keyframes)
        {
            LogInfo("WARNING: animated object [" + objectPathName + "] doesn't have the same keyframes for XYZ position curves. " +
                    "x: " + curveX.length + " y:" + curveY.length + " z:" + curveZ.length);
            return;
        }

        if (keyframes == 0)
        {
            return;
        }

        bool isFirstLevel = objectPathName.IndexOf('/') < 0;

        // Retrieve the keyframes of the position curves

        Keyframe[] keysX = curveX.keys;
        Keyframe[] keysY = curveY.keys;
        Keyframe[] keysZ = curveZ.keys;

        for (int k = 0; k < keyframes; k++)
        {
            Vector3 pos = new Vector3(keysX[k].value, keysY[k].value, keysZ[k].value);

            if (isFirstLevel)
            {
                if (m_zReverse)
                {
                    // Turn around the local position

                    pos = Quaternion.AngleAxis(180.0f, Vector3.up) * pos;

                    // Tangents X and Z must be adjusted to match the new orientation

                    InvertTangents(ref keysX[k]);
                    InvertTangents(ref keysZ[k]);
                }
            }
            else
            {
                // Position in the 2nd level objects must compensante the X+90 rotation that
                // has been applied to 1st level.

                Quaternion q = Quaternion.AngleAxis(-90.0f, Vector3.right);
                if (m_zReverse)
                {
                    q = Quaternion.AngleAxis(180.0f, Vector3.up) * q;
                }
                pos = q * pos;

                // Adjust the tangents of the Y and Z curves as result of the rotation X-90

                float inT  = keysZ[k].inTangent;
                float outT = keysZ[k].outTangent;
                keysZ[k].inTangent  = -keysY[k].inTangent;
                keysZ[k].outTangent = -keysY[k].outTangent;
                keysY[k].inTangent  = inT;
                keysY[k].outTangent = outT;

                // If the model has been turned around (180º) the tangents for X and Z position
                // curves must be inverted as well.

                if (m_zReverse)
                {
                    InvertTangents(ref keysX[k]);
                    InvertTangents(ref keysZ[k]);
                }
            }

            if (m_floatFix)
            {
                pos = FixVector3(pos, m_floatFixThreshold);
            }

            keysX[k].value = pos.x;
            keysY[k].value = pos.y;
            keysZ[k].value = pos.z;
        }

        // Assign the fixed keyframes back to the position curves

        curveX.keys = keysX;
        curveY.keys = keysY;
        curveZ.keys = keysZ;

        AnimationUtility.SetEditorCurve(clip, bindX, curveX);
        AnimationUtility.SetEditorCurve(clip, bindY, curveY);
        AnimationUtility.SetEditorCurve(clip, bindZ, curveZ);
    }
 internal static extern AnimationClipStats GetAnimationClipStats(AnimationClip clip);
    // Animation manipulation functions ------------------------------------------------------------


    void ProcessClipRotation(AnimationClip clip, string objectPathName)
    {
        // Access the rotation curves for the given object

        EditorCurveBinding bindX = EditorCurveBinding.FloatCurve(objectPathName, typeof(Transform), "m_LocalRotation.x");
        EditorCurveBinding bindY = EditorCurveBinding.FloatCurve(objectPathName, typeof(Transform), "m_LocalRotation.y");
        EditorCurveBinding bindZ = EditorCurveBinding.FloatCurve(objectPathName, typeof(Transform), "m_LocalRotation.z");
        EditorCurveBinding bindW = EditorCurveBinding.FloatCurve(objectPathName, typeof(Transform), "m_LocalRotation.w");

        AnimationCurve curveX = AnimationUtility.GetEditorCurve(clip, bindX);
        AnimationCurve curveY = AnimationUtility.GetEditorCurve(clip, bindY);
        AnimationCurve curveZ = AnimationUtility.GetEditorCurve(clip, bindZ);
        AnimationCurve curveW = AnimationUtility.GetEditorCurve(clip, bindW);

        if (curveX == null || curveY == null || curveZ == null || curveW == null)
        {
            LogInfo("WARNING: animated object [" + objectPathName + "] doesn't have correct rotation curves");
            return;
        }

        int keyframes = curveX.length;

        if (curveY.length != keyframes || curveZ.length != keyframes || curveW.length != keyframes)
        {
            LogInfo("WARNING: animated object [" + objectPathName + "] doesn't have the same keyframes for XYZW rotation curves. " +
                    "x: " + curveX.length + " y:" + curveY.length + " z:" + curveZ.length + " w:" + curveW.length);
            return;
        }

        if (keyframes == 0)
        {
            return;
        }

        bool isFirstLevel = objectPathName.IndexOf('/') < 0;

        // Retrieve the keyframes of the rotation curves

        Keyframe[] keysX = curveX.keys;
        Keyframe[] keysY = curveY.keys;
        Keyframe[] keysZ = curveZ.keys;
        Keyframe[] keysW = curveW.keys;

        for (int k = 0; k < keyframes; k++)
        {
            Quaternion rot = new Quaternion(keysX[k].value, keysY[k].value, keysZ[k].value, keysW[k].value);

            // Convert rotation from Blender (Right-handed) to Unity (Left-handed).
            // Must have in mind the -90 rotation in the first level objects.

            if (isFirstLevel)
            {
                // This is the same as rot = rot * Quaternion.AngleAxis(90.0f, Vector3.right);
                // Idea courtesy of apatriarca (www.gamedev.net/topic/654682-quaternions-convert-between-left-right-handed-without-using-euler/)

                float s45 = Mathf.Sin(Mathf.PI / 4.0f);

                keysX[k].value = (rot.w + rot.x) * s45;
                keysY[k].value = (rot.y + rot.z) * s45;
                keysZ[k].value = (rot.z - rot.y) * s45;
                keysW[k].value = (rot.w - rot.x) * s45;

                // Perform the same operation with tangents

                float inTx  = (keysW[k].inTangent + keysX[k].inTangent) * s45;
                float inTy  = (keysY[k].inTangent + keysZ[k].inTangent) * s45;
                float inTz  = (keysZ[k].inTangent - keysY[k].inTangent) * s45;
                float inTw  = (keysW[k].inTangent - keysX[k].inTangent) * s45;
                float outTx = (keysW[k].outTangent + keysX[k].outTangent) * s45;
                float outTy = (keysY[k].outTangent + keysZ[k].outTangent) * s45;
                float outTz = (keysZ[k].outTangent - keysY[k].outTangent) * s45;
                float outTw = (keysW[k].outTangent - keysX[k].outTangent) * s45;

                keysX[k].inTangent  = inTx;
                keysY[k].inTangent  = inTy;
                keysZ[k].inTangent  = inTz;
                keysW[k].inTangent  = inTw;
                keysX[k].outTangent = outTx;
                keysY[k].outTangent = outTy;
                keysZ[k].outTangent = outTz;
                keysW[k].outTangent = outTw;
            }
            else
            {
                // Convert the rotation from Blender to Unity

                keysX[k].value = -rot.x;
                keysY[k].value = -rot.z;
                keysZ[k].value = rot.y;
                keysW[k].value = -rot.w;

                // Adjust and exchange tangents accordingly

                InvertTangents(ref keysX[k]);
                InvertTangents(ref keysW[k]);
                float inT  = keysY[k].inTangent;
                float outT = keysY[k].outTangent;
                keysY[k].inTangent  = -keysZ[k].inTangent;
                keysY[k].outTangent = -keysZ[k].outTangent;
                keysZ[k].inTangent  = inT;
                keysZ[k].outTangent = outT;
            }

            // Turn around the forward axis if required

            if (m_zReverse)
            {
                keysX[k].value = -keysX[k].value;
                keysZ[k].value = -keysZ[k].value;

                InvertTangents(ref keysX[k]);
                InvertTangents(ref keysZ[k]);
            }
        }

        // Assign the fixed keyframes back to the rotation curves

        curveX.keys = keysX;
        curveY.keys = keysY;
        curveZ.keys = keysZ;
        curveW.keys = keysW;

        AnimationUtility.SetEditorCurve(clip, bindX, curveX);
        AnimationUtility.SetEditorCurve(clip, bindY, curveY);
        AnimationUtility.SetEditorCurve(clip, bindZ, curveZ);
        AnimationUtility.SetEditorCurve(clip, bindW, curveW);
    }
        public static AnimationClipCurveData[] GetAllCurves(AnimationClip clip)
        {
            bool includeCurveData = true;

            return(GetAllCurves(clip, includeCurveData));
        }
    void Start()
    {
        Animation anim = gameObject.AddComponent <Animation>();

        // Assign a simple waving animation to the bottom bone



        gameObject.AddComponent <SkinnedMeshRenderer>();
        SkinnedMeshRenderer rend = GetComponent <SkinnedMeshRenderer>();


        // Build basic mesh
        Mesh mesh = new Mesh();

        mesh.vertices  = new Vector3[] { new Vector3(-1, 0, 0), new Vector3(1, 0, 0), new Vector3(-1, 5, 0), new Vector3(1, 5, 0) };
        mesh.uv        = new Vector2[] { new Vector2(0, 0), new Vector2(1, 0), new Vector2(0, 1), new Vector2(1, 1) };
        mesh.triangles = new int[] { 0, 1, 2, 1, 3, 2 };
        mesh.RecalculateNormals();

        // Assign mesh to mesh filter & renderer
        rend.material = new Material(Shader.Find("Diffuse"));

        // Assign bone weights to mesh
        // We use 2 bones. One for the lower vertices, one for the upper vertices.
        BoneWeight[] weights = new BoneWeight[4];

        weights[0].boneIndex0 = 0;
        weights[0].weight0    = 0.3f;

        weights[1].boneIndex0 = 0;
        weights[1].weight0    = 1;

        weights[2].boneIndex0 = 1;
        weights[2].weight0    = 0.8f;

        weights[3].boneIndex0 = 1;
        weights[3].weight0    = 1;

        // A BoneWeights array (weights) was just created and the boneIndex and weight assigned.
        // The weights array will now be assigned to the boneWeights array in the Mesh.
        mesh.boneWeights = weights;

        // Create Bone Transforms and Bind poses
        // One bone at the bottom and one at the top
        Transform[] bones     = new Transform[2];
        Matrix4x4[] bindPoses = new Matrix4x4[2];

        bones[0]        = new GameObject("Lower").transform;
        bones[0].parent = transform;
        // Set the position relative to the parent
        bones[0].localRotation = Quaternion.identity;
        bones[0].localPosition = Vector3.zero;

        // The bind pose is bone's inverse transformation matrix
        // In this case the matrix we also make this matrix relative to the root
        // So that we can move the root game object around freely
        bindPoses[0] = bones[0].worldToLocalMatrix * transform.localToWorldMatrix;

        bones[1]        = new GameObject("Upper").transform;
        bones[1].parent = transform;
        // Set the position relative to the parent
        bones[1].localRotation = Quaternion.identity;
        bones[1].localPosition = new Vector3(0, 5, 0);
        // The bind pose is bone's inverse transformation matrix
        // In this case the matrix we also make this matrix relative to the root
        // So that we can move the root game object around freely
        bindPoses[1] = bones[1].worldToLocalMatrix * transform.localToWorldMatrix;

        // assign the bindPoses array to the bindposes array which is part of the mesh.
        mesh.bindposes = bindPoses;

        // Assign bones and bind poses
        rend.bones      = bones;
        rend.sharedMesh = mesh;

        AnimationCurve curve = new AnimationCurve();

        curve.keys = new Keyframe[] { new Keyframe(0, 0, 0, 0), new Keyframe(3, 60, 0, 0), new Keyframe(6, 0.0F, 0, 0) };

        // Create the clip with the curve
        AnimationClip clip = new AnimationClip();

        clip.legacy   = true;
        clip.wrapMode = WrapMode.Loop;
        //clip.SetCurve("Upper", typeof(Transform), "localPosition.z", curve);
        clip.SetCurve("Upper", typeof(Transform), "localEulerAngles.x", curve);
        // Add and play the clip
        anim.AddClip(clip, "test");
        anim.Play("test");
    }
 public static void SetEditorCurve(AnimationClip clip, string relativePath, Type type, string propertyName, AnimationCurve curve)
 {
     SetEditorCurve(clip, EditorCurveBinding.FloatCurve(relativePath, type, propertyName), curve);
 }
Beispiel #56
0
    private static void readMesh(string path, string filename, string texturepath)
    {
        string importingAssetsDir;

        if (File.Exists(path + "/" + filename))
        {
            Assimp.PostProcessSteps flags = (
                //  Assimp.PostProcessSteps.MakeLeftHanded |
                Assimp.PostProcessSteps.Triangulate |
                Assimp.PostProcessSteps.CalculateTangentSpace |
                Assimp.PostProcessSteps.GenerateUVCoords |
                Assimp.PostProcessSteps.GenerateSmoothNormals |
                Assimp.PostProcessSteps.RemoveComponent |
                Assimp.PostProcessSteps.JoinIdenticalVertices);

            IntPtr config = Assimp.aiCreatePropertyStore();

            Assimp.aiSetImportPropertyFloat(config, Assimp.AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE, 60.0f);
            Assimp.aiSetImportPropertyInteger(config, Assimp.AI_CONFIG_PP_LBW_MAX_WEIGHTS, 4);
            //  IntPtr scene = Assimp.aiImportFile(path + "/" + filename, (uint)flags);
            IntPtr scene = Assimp.aiImportFileWithProperties(path + "/" + filename, (uint)flags, config);
            Assimp.aiReleasePropertyStore(config);
            if (scene == null)
            {
                Debug.LogWarning("failed to read file: " + path + "/" + filename);
                return;
            }
            else
            {
                string nm = Path.GetFileNameWithoutExtension(filename);


                importingAssetsDir = "Assets/Prefabs/" + nm + "/";

                if (saveAssets)
                {
                    if (!Directory.Exists(importingAssetsDir))
                    {
                        Directory.CreateDirectory(importingAssetsDir);
                    }
                    AssetDatabase.Refresh();
                }


                GameObject ObjectRoot    = new GameObject(nm);
                GameObject meshContainer = new GameObject(nm + "_Mesh");
                meshContainer.transform.parent = ObjectRoot.transform;



                //  List<CombineInstance> combineInstances = new List<CombineInstance>();
                List <Material>   materials = new List <Material>();
                List <AssimpMesh> MeshList  = new List <AssimpMesh>();


                for (int i = 0; i < Assimp.aiScene_GetNumMaterials(scene); i++)
                {
                    string matName = Assimp.aiMaterial_GetName(scene, i);
                    matName = nm + "_mat" + i;

                    //  string fname = Path.GetFileNameWithoutExtension(Assimp.aiMaterial_GetTexture(scene, i, (int)Assimp.TextureType.Diffuse));
                    string fname = Path.GetFileName(Assimp.aiMaterial_GetTexture(scene, i, (int)Assimp.TextureType.Diffuse));
                    Debug.Log("texture " + fname + "Material :" + matName);

                    Color ambient  = Assimp.aiMaterial_GetAmbient(scene, i);
                    Color diffuse  = Assimp.aiMaterial_GetDiffuse(scene, i);
                    Color specular = Assimp.aiMaterial_GetSpecular(scene, i);
                    Color emissive = Assimp.aiMaterial_GetEmissive(scene, i);

                    Material mat = new Material(Shader.Find("Diffuse"));
                    mat.name  = matName;
                    mat.color = diffuse;

                    //	Debug.Log(ambient.ToString());
                    //	Debug.Log(diffuse.ToString());
                    //	Debug.Log(specular.ToString());
                    //	Debug.Log(emissive.ToString());


                    string texturename = path + "/" + fname;

                    Texture2D tex = null;
                    if (File.Exists(texturename))
                    {
                        tex = (Texture2D)AssetDatabase.LoadAssetAtPath(texturename, typeof(Texture2D));
                    }
                    else
                    if (File.Exists(texturename + ".PNG"))
                    {
                        tex = (Texture2D)AssetDatabase.LoadAssetAtPath(texturename + ".PNG", typeof(Texture2D));
                    }
                    else
                    if (File.Exists(texturename + ".JPG"))
                    {
                        tex = (Texture2D)AssetDatabase.LoadAssetAtPath(texturename + ".JPG", typeof(Texture2D));
                    }
                    else
                    if (File.Exists(texturename + ".BMP"))
                    {
                        tex = (Texture2D)AssetDatabase.LoadAssetAtPath(texturename + ".BMP", typeof(Texture2D));
                    }
                    else
                    if (File.Exists(texturename + ".TGA"))
                    {
                        tex = (Texture2D)AssetDatabase.LoadAssetAtPath(texturename + ".TGA", typeof(Texture2D));
                    }
                    else
                    if (File.Exists(texturename + ".DDS"))
                    {
                        tex = (Texture2D)AssetDatabase.LoadAssetAtPath(texturename + ".DDS", typeof(Texture2D));
                    }

                    if (tex != null)
                    {
                        Debug.Log("LOAD (" + texturename + ") texture");
                        mat.SetTexture("_MainTex", tex);
                    }
                    else
                    {
                        Debug.LogError("Fail LOAD (" + texturename + ") error");
                    }


                    if (saveAssets)
                    {
                        string materialAssetPath = AssetDatabase.GenerateUniqueAssetPath(importingAssetsDir + mat.name + ".asset");
                        AssetDatabase.CreateAsset(mat, materialAssetPath);
                    }
                    materials.Add(mat);
                }


                AssetDatabase.Refresh();

                if (Assimp.aiScene_GetRootNode(scene) != null)
                {
                    ObjectRoot.transform.position = Assimp.aiNode_GetPosition(Assimp.aiScene_GetRootNode(scene));

                    //assimp quaternion is w,x,y,z and unity x,y,z,w bu int this lib i fix this for unity
                    Quaternion assQuad = Assimp.aiNode_GetRotation(Assimp.aiScene_GetRootNode(scene));
                    ObjectRoot.transform.rotation = assQuad;


                    GameObject skeleton = new GameObject("Skeleton");
                    skeleton.transform.parent = ObjectRoot.transform;
                    processNodes(scene, Assimp.aiScene_GetRootNode(scene), ref listJoints);

                    for (int i = 0; i < listJoints.Count; i++)
                    {
                        AssimpJoint joint = listJoints[i];
                        Transform   bone  = GameObject.CreatePrimitive(PrimitiveType.Sphere).transform;
                        //	bone.transform.localScale.Set(2,2,2);
                        //    Transform bone = new GameObject(joint.Name).transform;
                        //   DebugBone debug = (DebugBone)bone.gameObject.AddComponent(typeof(DebugBone));



                        bone.name   = joint.Name;
                        bone.parent = skeleton.transform;

                        if (getBoneByName(joint.parentName) != null)
                        {
                            int index = findBoneByName(joint.parentName);
                            bone.parent = joint.parent.transform;
                        }
                        bone.localPosition = joint.Position;
                        bone.localRotation = joint.Orientation;

                        joint.transform = bone;
                    }
                }



                if (Assimp.aiScene_HasMeshes(scene))
                {
                    for (int i = 0; i < Assimp.aiScene_GetNumMeshes(scene); i++)
                    {
                        string name = "Mesh_";
                        name += i.ToString();


                        bool HasNormals  = Assimp.aiMesh_HasNormals(scene, i);
                        bool HasTexCoord = Assimp.aiMesh_HasTextureCoords(scene, i, 0);
                        bool HasFaces    = Assimp.aiMesh_HasFaces(scene, i);


                        AssimpMesh mesh = new AssimpMesh(meshContainer, ObjectRoot, name);
                        mesh.setmaterial(materials[Assimp.aiMesh_GetMaterialIndex(scene, i)]);
                        MeshList.Add(mesh);



                        for (int v = 0; v < Assimp.aiMesh_GetNumVertices(scene, i); v++)
                        {
                            Vector3 vertex = Assimp.aiMesh_Vertex(scene, i, v);
                            Vector3 n      = Assimp.aiMesh_Normal(scene, i, v);
                            float   x      = Assimp.aiMesh_TextureCoordX(scene, i, v, 0);
                            float   y      = Assimp.aiMesh_TextureCoordY(scene, i, v, 0);

                            Vector3 binormalf = Assimp.aiMesh_Bitangent(scene, i, v);
                            Vector3 tangentf  = Assimp.aiMesh_Tangent(scene, i, v);

                            Vector4 outputTangent = new Vector4(tangentf.x, tangentf.y, tangentf.z, 0.0F);

                            float dp = Vector3.Dot(Vector3.Cross(n, tangentf), binormalf);
                            if (dp > 0.0F)
                            {
                                outputTangent.w = 1.0F;
                            }
                            else
                            {
                                outputTangent.w = -1.0F;
                            }


                            mesh.addVertex(vertex, n, outputTangent, new Vector2(x, y));
                        }

                        for (int f = 0; f < Assimp.aiMesh_GetNumFaces(scene, i); f++)
                        {
                            int a = Assimp.aiMesh_Indice(scene, i, f, 0);
                            int b = Assimp.aiMesh_Indice(scene, i, f, 1);
                            int c = Assimp.aiMesh_Indice(scene, i, f, 2);
                            mesh.addFace(a, b, c);
                        }



                        //****
                        int numBone = Assimp.aiMesh_GetNumBones(scene, i);


                        for (int b = 0; b < numBone; b++)
                        {
                            string      bname  = Assimp.aiMesh_GetBoneName(scene, i, b);
                            AssimpJoint joint  = getBoneByName(bname);
                            int         boneID = findBoneByName(bname);


                            int numWeights = Assimp.aiMesh_GetNumBoneWeights(scene, i, b);
                            for (int w = 0; w < numWeights; w++)
                            {
                                float Weight   = Assimp.aiMesh_GetBoneWeight(scene, i, b, w);
                                int   VertexId = Assimp.aiMesh_GetBoneVertexId(scene, i, b, w);
                                mesh.addBone(VertexId, boneID, Weight);
                            }
                        }

                        for (int j = 0; j < listJoints.Count; j++)
                        {
                            AssimpJoint joint = listJoints[j];
                            mesh.addJoint(joint);
                        }

                        //**********


                        mesh.BuilSkin();
                        mesh.build();


                        if (saveAssets)
                        {
                            string meshAssetPath = AssetDatabase.GenerateUniqueAssetPath(importingAssetsDir + mesh.name + ".asset");
                            AssetDatabase.CreateAsset(mesh.geometry, meshAssetPath);
                        }


                        mesh.dispose();
                    }
                }



                //create key frames
                if (Assimp.aiScene_HasAnimation(scene))
                {
                    Animation anim = (UnityEngine.Animation)ObjectRoot.AddComponent(typeof(Animation));

                    int numAnimation = Assimp.aiScene_GetNumAnimations(scene);

                    Debug.Log("count animation  :" + numAnimation);


                    for (int a = 0; a < numAnimation; a++)
                    {
                        AnimationClip clip  = new AnimationClip();
                        string        anima = Assimp.aiAnim_GetName(scene, a);
                        clip.name   = nm + "_" + anima + "_" + a;
                        clip.legacy = true;

                        clip.wrapMode = WrapMode.Loop;

                        float tinks = (float)Assimp.aiAnim_GetTicksPerSecond(scene, a);
                        if (tinks <= 1f)
                        {
                            tinks = 1f;
                        }
                        float fps = tinks;
                        clip.frameRate = tinks;


                        Debug.Log("animation fps :" + fps);



                        int numchannels = Assimp.aiAnim_GetNumChannels(scene, a);
                        for (int i = 0; i < numchannels; i++)
                        {
                            string      name  = Assimp.aiAnim_GetChannelName(scene, a, i);
                            AssimpJoint joint = getBoneByName(name);



                            //  Debug.Log(String.Format("anim channel {0} bone name {1}  poskeys {2}  rotkeys{2}", i, name, Assimp.aiAnim_GetNumPositionKeys(scene, 0, i), Assimp.aiAnim_GetNumRotationKeys(scene, 0, i)));

                            //public static bool ignoreRotations = true;
                            // public static bool ignorePositions = true;
                            // public static bool ignoreScalling = true;

                            if (!ignoreScalling)
                            {
                                if (Assimp.aiAnim_GetNumScalingKeys(scene, a, i) != 0)
                                {
                                    AnimationCurve scaleXcurve = new AnimationCurve();
                                    AnimationCurve scaleYcurve = new AnimationCurve();
                                    AnimationCurve scaleZcurve = new AnimationCurve();

                                    for (int j = 0; j < Assimp.aiAnim_GetNumScalingKeys(scene, a, i); j++)
                                    {
                                        float   time  = (float)Assimp.aiAnim_GetScalingFrame(scene, a, i, j);// / fps;
                                        Vector3 scale = Assimp.aiAnim_GetScalingKey(scene, a, i, j);
                                        scaleXcurve.AddKey(time, scale.x);
                                        scaleYcurve.AddKey(time, scale.y);
                                        scaleZcurve.AddKey(time, scale.z);
                                    }
                                    clip.SetCurve("Skeleton/" + joint.Path, typeof(Transform), "m_LocalScale.x", scaleXcurve);
                                    clip.SetCurve("Skeleton/" + joint.Path, typeof(Transform), "m_LocalScale.y", scaleYcurve);
                                    clip.SetCurve("Skeleton/" + joint.Path, typeof(Transform), "m_LocalScale.z", scaleZcurve);
                                }
                            }

                            if (!ignorePositions)
                            {
                                if (Assimp.aiAnim_GetNumPositionKeys(scene, a, i) != 0)
                                {
                                    AnimationCurve posXcurve = new AnimationCurve();
                                    AnimationCurve posYcurve = new AnimationCurve();
                                    AnimationCurve posZcurve = new AnimationCurve();


                                    for (int j = 0; j < Assimp.aiAnim_GetNumPositionKeys(scene, a, i); j++)
                                    {
                                        float   time = (float)Assimp.aiAnim_GetPositionFrame(scene, a, i, j);// / fps;
                                        Vector3 pos  = Assimp.aiAnim_GetPositionKey(scene, a, i, j);
                                        posXcurve.AddKey(time, pos.x);
                                        posYcurve.AddKey(time, pos.y);
                                        posZcurve.AddKey(time, pos.z);
                                    }

                                    clip.SetCurve("Skeleton/" + joint.Path, typeof(Transform), "localPosition.x", posXcurve);
                                    clip.SetCurve("Skeleton/" + joint.Path, typeof(Transform), "localPosition.y", posYcurve);
                                    clip.SetCurve("Skeleton/" + joint.Path, typeof(Transform), "localPosition.z", posZcurve);
                                }
                            }

                            if (!ignoreRotations)
                            {
                                if (Assimp.aiAnim_GetNumRotationKeys(scene, a, i) != 0)
                                {
                                    AnimationCurve rotXcurve = new AnimationCurve();
                                    AnimationCurve rotYcurve = new AnimationCurve();
                                    AnimationCurve rotZcurve = new AnimationCurve();
                                    AnimationCurve rotWcurve = new AnimationCurve();

                                    for (int j = 0; j < Assimp.aiAnim_GetNumRotationKeys(scene, a, i); j++)
                                    {
                                        float time = (float)Assimp.aiAnim_GetRotationFrame(scene, a, i, j);// / fps;

                                        Quaternion rotation = Assimp.aiAnim_GetRotationKey(scene, a, i, j);
                                        rotXcurve.AddKey(time, rotation.x);
                                        rotYcurve.AddKey(time, rotation.y);
                                        rotZcurve.AddKey(time, rotation.z);
                                        rotWcurve.AddKey(time, rotation.w);
                                    }

                                    clip.SetCurve("Skeleton/" + joint.Path, typeof(Transform), "localRotation.x", rotXcurve);
                                    clip.SetCurve("Skeleton/" + joint.Path, typeof(Transform), "localRotation.y", rotYcurve);
                                    clip.SetCurve("Skeleton/" + joint.Path, typeof(Transform), "localRotation.z", rotZcurve);
                                    clip.SetCurve("Skeleton/" + joint.Path, typeof(Transform), "localRotation.w", rotWcurve);
                                }
                            }
                        }



                        clip.EnsureQuaternionContinuity();
                        anim.AddClip(clip, clip.name);
                        anim.clip = clip;

                        string clipAssetPath = AssetDatabase.GenerateUniqueAssetPath(importingAssetsDir + clip.name + ".asset");
                        AssetDatabase.CreateAsset(clip, clipAssetPath);

                        //     AssetDatabase.CreateAsset(clip, "Assets/Models/" + nm +"_"+a+ ".anim");
                        //    AssetDatabase.SaveAssets();
                    }
                }


                if (saveAssets)
                {
                    string prefabPath = AssetDatabase.GenerateUniqueAssetPath(importingAssetsDir + filename + ".prefab");
                    var    prefab     = PrefabUtility.CreateEmptyPrefab(prefabPath);
                    PrefabUtility.ReplacePrefab(ObjectRoot, prefab, ReplacePrefabOptions.ConnectToPrefab);
                    AssetDatabase.Refresh();
                }

                MeshList.Clear();
            }

            listJoints.Clear();

            Assimp.aiReleaseImport(scene);
            Debug.LogWarning(path + "/" + filename + " Imported ;) ");
        }
    }
    public static void RebuildUnitAnimController()
    {
        // Warn about controller overwrite.
        // Gather all clips from folder.
        // Gather all anims from anim decl and build those with clips.

        string clipsAssetPath = "Assets/Animations/Unit";

        string[] assetGUIDs = AssetDatabase.FindAssets("", new string[] { clipsAssetPath });

        Dictionary <string, AnimationClip> clips = new Dictionary <string, AnimationClip>();

        foreach (string str in assetGUIDs)
        {
            string assetPath = AssetDatabase.GUIDToAssetPath(str);

            if (assetPath.EndsWith(".fbx"))
            {
                UnityEngine.Object[] allAssets = AssetDatabase.LoadAllAssetsAtPath(assetPath);

                foreach (UnityEngine.Object obj in allAssets)
                {
                    if (obj.GetType() == typeof(AnimationClip))
                    {
                        AnimationClip clip = obj as AnimationClip;
                        clips[clip.name] = clip;
                    }
                }
            }
        }

        AnimatorController   controller = AnimatorController.CreateAnimatorControllerAtPath("Assets/Animations/unitAnimController.controller");
        AnimatorStateMachine rootState  = controller.layers[0].stateMachine;

        for (int i = 0; i < Animation.FBXEntries.Length; ++i)
        {
            AnimationClip clip = null;

            if (clips.TryGetValue(Animation.FBXEntries[i].mName, out clip))
            {
                Debug.Log("Match for: " + clip.name);

                AnimatorState state = rootState.AddState(clip.name);
                state.motion = clip;
                state.speed  = Animation.FBXEntries[i].mSpeed;
            }
        }

        string defaultState = Animation.GetDefaultAnimation();

        for (int i = 0; i < rootState.states.Length; ++i)
        {
            if (rootState.states[i].state.name == defaultState)
            {
                rootState.defaultState = rootState.states[i].state;
                break;
            }
        }

        //AnimatorStateMachine rootState = controller.layers[0].stateMachine;
        //AnimatorState state = rootState.AddState("run");
        //state.add = newClips[0];
        //controller
        //AnimationClip a = new AnimationClip();
        //controller.AddMotion(a);

        //AnimationClip[] clip = AssetDatabase.LoadAllAssetsAtPath("Assets/Models/new_char_rig.fbx/", typeof(AnimationClip)) as AnimationClip[];

        //controller.AddMotion(clip);
    }
Beispiel #58
0
 void OnPostprocessAnimation(GameObject root, AnimationClip clip)
 {
 }
Beispiel #59
0
        private static IEnumerator LoadAsync(string json, string filepath, byte[] bytefile, long binChunkStart, ImportSettings importSettings, Action <GameObject, AnimationClip[]> onFinished, Action <float> onProgress = null)
        {
            // Threaded deserialization
            Task <GLTFObject> deserializeTask = new Task <GLTFObject>(() => JsonConvert.DeserializeObject <GLTFObject>(json));

            deserializeTask.Start();
            while (!deserializeTask.IsCompleted)
            {
                yield return(null);
            }
            GLTFObject gltfObject = deserializeTask.Result;

            CheckExtensions(gltfObject);

            // directory root is sometimes used for loading buffers from containing file, or local images
            string directoryRoot = filepath != null?Directory.GetParent(filepath).ToString() + "/" : null;

            importSettings.shaderOverrides.CacheDefaultShaders();

            // Setup import tasks
            List <ImportTask> importTasks = new List <ImportTask>();

            GLTFBuffer.ImportTask bufferTask = new GLTFBuffer.ImportTask(gltfObject.buffers, filepath, bytefile, binChunkStart);
            importTasks.Add(bufferTask);
            GLTFBufferView.ImportTask bufferViewTask = new GLTFBufferView.ImportTask(gltfObject.bufferViews, bufferTask);
            importTasks.Add(bufferViewTask);
            GLTFAccessor.ImportTask accessorTask = new GLTFAccessor.ImportTask(gltfObject.accessors, bufferViewTask);
            importTasks.Add(accessorTask);
            GLTFImage.ImportTask imageTask = new GLTFImage.ImportTask(gltfObject.images, directoryRoot, bufferViewTask);
            importTasks.Add(imageTask);
            GLTFTexture.ImportTask textureTask = new GLTFTexture.ImportTask(gltfObject.textures, imageTask);
            importTasks.Add(textureTask);
            GLTFMaterial.ImportTask materialTask = new GLTFMaterial.ImportTask(gltfObject.materials, textureTask, importSettings);
            importTasks.Add(materialTask);
            GLTFMesh.ImportTask meshTask = new GLTFMesh.ImportTask(gltfObject.meshes, accessorTask, bufferViewTask, materialTask, importSettings);
            importTasks.Add(meshTask);
            GLTFSkin.ImportTask skinTask = new GLTFSkin.ImportTask(gltfObject.skins, accessorTask);
            importTasks.Add(skinTask);
            GLTFNode.ImportTask nodeTask = new GLTFNode.ImportTask(gltfObject.nodes, meshTask, skinTask, gltfObject.cameras);
            importTasks.Add(nodeTask);

            // Ignite
            for (int i = 0; i < importTasks.Count; i++)
            {
                TaskSupervisor(importTasks[i], onProgress).RunCoroutine();
            }

            // Wait for all tasks to finish
            while (!importTasks.All(x => x.IsCompleted))
            {
                yield return(null);
            }

            // Fire onFinished when all tasks have completed
            GameObject root = nodeTask.Result.GetRoot();

            GLTFAnimation.ImportResult[] animationResult = gltfObject.animations.Import(accessorTask.Result, nodeTask.Result, importSettings);
            AnimationClip[] animations = new AnimationClip[0];
            if (animationResult != null)
            {
                animations = animationResult.Select(x => x.clip).ToArray();
            }
            if (onFinished != null)
            {
                onFinished(nodeTask.Result.GetRoot(), animations);
            }

            // Close file streams
            foreach (var item in bufferTask.Result)
            {
                item.Dispose();
            }
        }
        public void GenerateInventory()
        {
            string generatedDirPath = $"Assets/Merlin/Inventory/_generated/{descriptorGUID}";

            if (!Directory.Exists(generatedDirPath))
            {
                Directory.CreateDirectory(generatedDirPath);
            }

            // Generate the stage parameters for the inventory toggles
            VRCExpressionParameters inventoryStageParams;
            string stageParameterPath = $"{generatedDirPath}/customStageParams.asset";

            if (basisStageParameters != null)
            {
                AssetDatabase.CopyAsset(AssetDatabase.GetAssetPath(basisStageParameters), stageParameterPath);
                inventoryStageParams = AssetDatabase.LoadAssetAtPath <VRCExpressionParameters>(stageParameterPath);
            }
            else
            {
                inventoryStageParams = ScriptableObject.CreateInstance <VRCExpressionParameters>();
                AssetDatabase.CreateAsset(inventoryStageParams, $"{generatedDirPath}/customStageParams.asset");
            }

            List <VRCExpressionParameters.Parameter> originalParams = new List <VRCExpressionParameters.Parameter>();

            if (inventoryStageParams.parameters != null)
            {
                foreach (VRCExpressionParameters.Parameter param in inventoryStageParams.parameters)
                {
                    if (!string.IsNullOrEmpty(param.name))
                    {
                        originalParams.Add(new VRCExpressionParameters.Parameter()
                        {
                            name = param.name, valueType = param.valueType
                        });
                    }
                }
            }

            if (inventorySlots.Length + originalParams.Count > 16)
            {
                Debug.LogError($"Cannot have more than {16 - originalParams.Count} inventory slots");
                return;
            }

            VRCExpressionParameters.Parameter[] basisParameters = inventoryStageParams.parameters;
            inventoryStageParams.parameters = new VRCExpressionParameters.Parameter[16];

            for (int i = 0; i < originalParams.Count; ++i)
            {
                inventoryStageParams.parameters[i] = originalParams[i];
            }

            for (int i = originalParams.Count; i < inventorySlots.Length + originalParams.Count; ++i)
            {
                inventoryStageParams.parameters[i] = new VRCExpressionParameters.Parameter()
                {
                    name = $"GenInventorySlot{i - originalParams.Count}", valueType = VRCExpressionParameters.ValueType.Int
                }
            }
            ;

            for (int i = originalParams.Count + inventorySlots.Length; i < 16; ++i) // Clear out empty params
            {
                inventoryStageParams.parameters[i] = new VRCExpressionParameters.Parameter()
                {
                    name = "", valueType = VRCExpressionParameters.ValueType.Float
                }
            }
            ;

            // Generate menu asset
            VRCExpressionsMenu menuAsset;
            string             menuPath = $"{generatedDirPath}/expressionMenu.asset";

            if (basisMenu)
            {
                AssetDatabase.CopyAsset(AssetDatabase.GetAssetPath(basisMenu), menuPath);
                menuAsset = AssetDatabase.LoadAssetAtPath <VRCExpressionsMenu>(menuPath);
            }
            else
            {
                menuAsset = ScriptableObject.CreateInstance <VRCExpressionsMenu>();
                AssetDatabase.CreateAsset(menuAsset, menuPath);
            }

            for (int i = 0; i < inventorySlots.Length; ++i)
            {
                menuAsset.controls.Add(new VRCExpressionsMenu.Control()
                {
                    icon      = inventorySlots[i].slotIcon,
                    name      = inventorySlots[i].slotName,
                    parameter = new VRCExpressionsMenu.Control.Parameter()
                    {
                        name = $"GenInventorySlot{i}"
                    },
                    type  = VRCExpressionsMenu.Control.ControlType.Toggle,
                    value = 1,
                });
            }

            // Generate controller
            AnimatorController controller;
            string             controllerPath = $"{generatedDirPath}/inventoryController.controller";

            if (basisAnimator)
            {
                AssetDatabase.CopyAsset(AssetDatabase.GetAssetPath(basisAnimator), controllerPath);

                controller = AssetDatabase.LoadAssetAtPath <AnimatorController>(controllerPath);
            }
            else
            {
                controller = AnimatorController.CreateAnimatorControllerAtPath(controllerPath);
            }

            AnimationClip[] inventoryClips = new AnimationClip[inventorySlots.Length];

            // Generate layer mask
            AvatarMask maskEverything = new AvatarMask();

            for (int i = 0; i < (int)AvatarMaskBodyPart.LastBodyPart; ++i)
            {
                maskEverything.SetHumanoidBodyPartActive((AvatarMaskBodyPart)i, false);
            }

            maskEverything.name = "maskEverythingMask";
            AssetDatabase.AddObjectToAsset(maskEverything, controller);

            // Generate animation clips
            for (int i = 0; i < inventorySlots.Length; ++i)
            {
                InventorySlot slot = inventorySlots[i];

                // Set initial object state
                foreach (GameObject toggleObject in slot.slotToggleItems)
                {
                    if (toggleObject)
                    {
                        toggleObject.SetActive(slot.startEnabled);
                    }
                }

                string        animationClipPath = $"{generatedDirPath}/Animations/_toggle{i}.anim";
                AnimationClip toggleClip        = GenerateToggleClip(slot.slotToggleItems, !slot.startEnabled);

                //AssetDatabase.CreateAsset(toggleClip, animationClipPath);

                inventoryClips[i] = toggleClip;

                toggleClip.name = $"toggleAnim{i}";
                AssetDatabase.AddObjectToAsset(toggleClip, controller);
            }

            // Generate controller layers
            for (int i = 0; i < inventorySlots.Length; ++i)
            {
                string paramName = $"GenInventorySlot{i}";
                controller.AddParameter(paramName, AnimatorControllerParameterType.Int);

                string layerName = $"GenToggleLayer{i}";

                AnimatorControllerLayer toggleLayer = new AnimatorControllerLayer();
                toggleLayer.name                   = layerName;
                toggleLayer.defaultWeight          = 1f;
                toggleLayer.stateMachine           = new AnimatorStateMachine();
                toggleLayer.stateMachine.name      = toggleLayer.name;
                toggleLayer.stateMachine.hideFlags = HideFlags.HideInHierarchy;
                toggleLayer.avatarMask             = maskEverything;

                if (AssetDatabase.GetAssetPath(controller) != "")
                {
                    AssetDatabase.AddObjectToAsset(toggleLayer.stateMachine, AssetDatabase.GetAssetPath(controller));
                }

                AnimatorStateMachine stateMachine = toggleLayer.stateMachine;

                AnimatorState nullState   = stateMachine.AddState("Null State", stateMachine.entryPosition + new Vector3(200f, 0f));
                AnimatorState toggleState = stateMachine.AddState("Toggle Triggered", stateMachine.entryPosition + new Vector3(500f, 0f));
                toggleState.motion = inventoryClips[i];

                AnimatorStateTransition toToggle = nullState.AddTransition(toggleState);
                toToggle.exitTime         = 0f;
                toToggle.hasExitTime      = false;
                toToggle.hasFixedDuration = true;
                toToggle.duration         = 0f;

                AnimatorStateTransition toNull = toggleState.AddTransition(nullState);
                toNull.exitTime         = 0f;
                toNull.hasExitTime      = false;
                toNull.hasFixedDuration = true;
                toNull.duration         = 0f;

                toToggle.AddCondition(AnimatorConditionMode.Greater, 0f, paramName);
                toNull.AddCondition(AnimatorConditionMode.Equals, 0f, paramName);

                controller.AddLayer(toggleLayer);
            }

            // Setup layers on the avatar descriptor
            VRCAvatarDescriptor descriptor = GetComponent <VRCAvatarDescriptor>();

            descriptor.expressionsMenu      = menuAsset;
            descriptor.expressionParameters = inventoryStageParams;

            VRCAvatarDescriptor.CustomAnimLayer layer = new VRCAvatarDescriptor.CustomAnimLayer();
            layer.isDefault          = false;
            layer.animatorController = controller;
            layer.type = inventoryAnimLayer;

            for (int i = 0; i < descriptor.baseAnimationLayers.Length; ++i)
            {
                if (descriptor.baseAnimationLayers[i].type == inventoryAnimLayer)
                {
                    descriptor.baseAnimationLayers[i] = layer;
                    break;
                }
            }

            AssetDatabase.SaveAssets();
        }