예제 #1
0
        internal IKPose GetIkPose(PmdModel pmdModel)
        {
            var ikPose           = new IKPose();
            var normalPose       = ikPose.NormalPose;
            var endEffectorGoals = ikPose.EndEffectorGoals;

            var assignableBoneTypes = new[] { Bone.BONE_ROTATE,
                                              Bone.BONE_ROTATE_TRANSLATE,
                                              Bone.BONE_IK_ROTATION_INFLUENCED,
                                              Bone.BONE_IK_TARGET };
            JointChange jointChange;

            for (int boneIndex = 0; boneIndex < pmdModel.Bones.Count; boneIndex++)
            {
                var bone = pmdModel.Bones.ElementAt(boneIndex);
                if (assignableBoneTypes.Contains(bone.BoneType))
                {
                    try
                    {
                        jointChange = GetRightHandedJointChange(bone.Name);
                    }
                    catch (KeyNotFoundException)
                    {
                        continue;
                    }
                    normalPose.SetJointChange(bone.Name, jointChange);
                }
                else if (bone.BoneType == Bone.BONE_ROTATION_INFLUENCED)
                {
                    var source_bone = pmdModel.Bones.ElementAt(bone.IkBoneIndex);
                    try
                    {
                        jointChange = GetRightHandedJointChange(source_bone.Name);
                    }
                    catch (KeyNotFoundException)
                    {
                        continue;
                    }
                    normalPose.SetJointChange(bone.Name, jointChange);
                }
                else if (bone.BoneType == Bone.BONE_IK)
                {
                    var ikChain         = pmdModel.GetIkChainByIkBoneIndex(boneIndex);
                    var endEffectorBone = pmdModel.Bones.ElementAt(ikChain.EndEffectorIndex);

                    var newPosition = pmdModel.GetMorphedWorldPosition(boneIndex, this);
                    endEffectorGoals.SetEndEffectorPosition(endEffectorBone.Name, newPosition);
                }
            }

            return(ikPose);
        }
예제 #2
0
파일: Game1.cs 프로젝트: kalluwa/playMiku
        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            Font.Initialze(GraphicsDevice, Content);

            miku = Content.Load <PmdModel>("Models/miku");
            miku.Initialize(GraphicsDevice, Content);
            anim = Content.Load <VmdAnimation>("Anims/Lamb");
            miku.SetAnim(anim);
            anim.AnimationSpeed = 0.1f;
            //bone helper
#if WINDOWS
            helper = new BoneHelper(GraphicsDevice, Content);
#endif

            // TODO: use this.Content to load your game content here
        }
예제 #3
0
        public PoseAnimation GetIkLessPoseAnimation(PmdModel pmdModel, Func <double, bool> progressHook)
        {
            var curves     = GetBoneCurves();
            var ikArmature = pmdModel.GetIkArmature();
            var ikPose     = new IKPose();
            var pose       = new Pose();

            var iterators = new Dictionary <string, IEnumerator <ControlPoint <JointChange> > >();

            foreach (var item in curves)
            {
                var boneName = item.Key;
                var curve    = item.Value;
                iterators[boneName] = curve.GetControlPointIterator();
            }

            var frames = new Dictionary <string, ControlPoint <JointChange> >();

            foreach (var item in iterators)
            {
                var boneName = item.Key;
                var iterator = item.Value;
                if (iterator.MoveNext())
                {
                    frames[boneName] = iterator.Current;
                }
            }

            var ikJointCurves = new Dictionary <string, Polyline <JointChange> >();

            foreach (var ikJoint in ikArmature.GetIkJoints())
            {
                ikJointCurves[ikJoint.Name] = new Polyline_JointChange();
            }

            while (frames.Count > 0)
            {
                var earliestTime = 1e20f;
                foreach (var item in frames)
                {
                    var boneName = item.Key;
                    var frame    = item.Value;
                    if (frame.Time < earliestTime)
                    {
                        earliestTime = frame.Time;
                    }
                }

                var vpd_pose = GetVpdPose(curves, pmdModel, earliestTime);
                pose = pmdModel.GetIkLessPose(vpd_pose);

                foreach (var item in ikJointCurves)
                {
                    var ikJointName = item.Key;
                    var curve       = item.Value;
                    curve.SetControlPoint(earliestTime, pose.GetJointChange(ikJointName));
                }

                var boneNamesWithEarliestTime = new List <string>();
                foreach (var item in frames)
                {
                    var boneName = item.Key;
                    var frame    = item.Value;
                    if (Math.Abs(frame.Time - earliestTime) < 0.0001)
                    {
                        boneNamesWithEarliestTime.Add(boneName);
                    }
                }

                foreach (var boneName in boneNamesWithEarliestTime)
                {
                    var iterator = iterators[boneName];
                    if (iterator.MoveNext())
                    {
                        frames[boneName] = iterator.Current;
                    }
                    else
                    {
                        frames.Remove(boneName);
                    }
                }

                if (progressHook != null)
                {
                    var continuing = progressHook(earliestTime);
                    if (!continuing)
                    {
                        return(null);
                    }
                }
            }

            var poseAnimation = new PoseAnimation();

            curves = new Dictionary <string, Polyline <JointChange> >();
            foreach (var boneFrame in boneFrames)
            {
                if (!curves.ContainsKey(boneFrame.BoneName))
                {
                    curves[boneFrame.BoneName] = new Polyline_JointChange();
                }
                var position = new Vector3D(boneFrame.Position.X, boneFrame.Position.Y, -boneFrame.Position.Z);
                // var z_flip_matrix = matrix4x4.scale(1, 1, -1);
                var orientation = new Quaternion(boneFrame.Orientation.X,
                                                 boneFrame.Orientation.Y,
                                                 -boneFrame.Orientation.Z,
                                                 -boneFrame.Orientation.W);
                curves[boneFrame.BoneName].SetControlPoint(boneFrame.FrameNumber,
                                                           new JointChange(position, orientation));
            }
            foreach (var item in curves)
            {
                var boneName = item.Key;
                var curve    = item.Value;
                if (pmdModel.BonesByName.ContainsKey(boneName))
                {
                    var bone = pmdModel.GetBoneByName(boneName);
                    if (bone.BoneType != Bone.BONE_IK)
                    {
                        poseAnimation.SetJointCurve(boneName, curve);
                    }
                }
            }
            foreach (var item in ikJointCurves)
            {
                var boneName     = item.Key;
                var ikJointCurve = item.Value;
                poseAnimation.SetJointCurve(boneName, ikJointCurve);
            }

            foreach (var bone in pmdModel.Bones)
            {
                if (bone.BoneType == Bone.BONE_ROTATION_INFLUENCED)
                {
                    var sourceBone = pmdModel.Bones.ElementAt(bone.IkBoneIndex);
                    var boneCurve  = new Polyline_JointChange();
                    if (curves.ContainsKey(sourceBone.Name))
                    {
                        var sourceCurve = curves[sourceBone.Name];
                        foreach (var controlPoint in sourceCurve.GetControlPoints())
                        {
                            var time = controlPoint.Time;
                            var jc   = controlPoint.Value;
                            boneCurve.SetControlPoint(time, new JointChange(new Vector3D(0, 0, 0), jc.Orientation));
                        }
                    }
                    poseAnimation.SetJointCurve(bone.Name, boneCurve);
                }
            }
            poseAnimation.UpdateRange();
            return(poseAnimation);
        }
예제 #4
0
        private VpdPose GetVpdPose(Dictionary <string, Polyline <JointChange> > curves, PmdModel pmdModel, float time)
        {
            var vpdPose = new VpdPose();

            foreach (var item in curves)
            {
                var boneName    = item.Key;
                var curve       = item.Value;
                var jointChange = curve.Evaluate(time);
                vpdPose.SetJointChange(boneName, jointChange);
            }

            return(vpdPose);
        }
예제 #5
0
파일: Game1.cs 프로젝트: kalluwa/playMiku
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            {
                this.Exit();
            }

            // TODO: Add your update logic here
            //update view
            if (g_bRotateCamera)
            {
                g_time   += gameTime.ElapsedGameTime.Milliseconds * 0.001f;
                CameraPos = new Vector3(g_fDistanceToMiku * (float)Math.Cos(g_time), height, g_fDistanceToMiku * (float)Math.Sin(g_time));
                View      = Matrix.CreateLookAt(CameraPos, new Vector3(0, height - 5, 0), new Vector3(0, 1, 0));
            }

            miku.Update(gameTime);


            #region Control
            //control region
            KeyboardState currentState      = Keyboard.GetState();
            MouseState    currentMouseState = Mouse.GetState();

            if (currentState.IsKeyDown(Keys.C) && lastKeyState.IsKeyUp(Keys.C))
            {
                miku = Content.Load <PmdModel>("Models/model_1");
                miku.Initialize(GraphicsDevice, Content);
                anim = Content.Load <VmdAnimation>("Anims/Lamb");
                miku.SetAnim(anim);
                anim.AnimationSpeed = 0.1f;
            }

            if (currentState.IsKeyDown(Keys.V) && lastKeyState.IsKeyUp(Keys.V))
            {
                miku = Content.Load <PmdModel>("Models/miku");
                miku.Initialize(GraphicsDevice, Content);
                anim = Content.Load <VmdAnimation>("Anims/Lamb");
                miku.SetAnim(anim);
                anim.AnimationSpeed = 0.1f;
            }
            if (currentState.IsKeyDown(Keys.Space) && lastKeyState.IsKeyUp(Keys.Space))
            {
                bShowAllBone = !bShowAllBone;
            }
            if (currentState.IsKeyDown(Keys.Enter) && lastKeyState.IsKeyUp(Keys.Enter))
            {
                g_bRotateCamera = !g_bRotateCamera;
            }
            if (currentState.IsKeyDown(Keys.P) && lastKeyState.IsKeyUp(Keys.P))
            {
                miku.Pause = !miku.Pause;
            }
            if (currentState.IsKeyDown(Keys.I) && lastKeyState.IsKeyUp(Keys.I))
            {
                miku.PauseBoneUpdate = !miku.PauseBoneUpdate;
            }
            //show ik bone
            if (currentState.IsKeyDown(Keys.K) && lastKeyState.IsKeyUp(Keys.K))
            {
                bShowIkBone = !bShowIkBone;
            }
            if (currentState.IsKeyDown(Keys.Up) && lastKeyState.IsKeyUp(Keys.Up))
            {
                showBoneIndex = (showBoneIndex + 1) % miku.BoneCount;
            }
            else if (currentState.IsKeyDown(Keys.Down) && lastKeyState.IsKeyUp(Keys.Down))
            {
                showBoneIndex = (showBoneIndex - 1 + miku.BoneCount) % miku.BoneCount;
            }
            if (currentState.IsKeyDown(Keys.Left))
            {
                showBoneIndex = (showBoneIndex + 1) % miku.BoneCount;
            }
            else if (currentState.IsKeyDown(Keys.Right))
            {
                showBoneIndex = (showBoneIndex - 1 + miku.BoneCount) % miku.BoneCount;
            }

            Vector3 forward = Vector3.Cross(CameraUp, CameraRight);
            forward.Normalize();

            if (currentState.IsKeyDown(Keys.W) || currentState.IsKeyDown(Keys.A) ||
                currentState.IsKeyDown(Keys.D) || currentState.IsKeyDown(Keys.S))
            {
                Vector3 moveMent = Vector3.Zero;
                if (currentState.IsKeyDown(Keys.W))
                {
                    moveMent = forward;
                }
                else if (currentState.IsKeyDown(Keys.S))
                {
                    moveMent = -forward;
                }
                if (currentState.IsKeyDown(Keys.A))
                {
                    moveMent = -CameraRight;
                }
                else if (currentState.IsKeyDown(Keys.D))
                {
                    moveMent = CameraRight;
                }
                moveMent     *= 0.05f;
                CameraPos    += moveMent;
                CameraTarget += moveMent;
                View          = Matrix.CreateLookAt(CameraPos, CameraTarget, CameraUp);
            }

            if ((lastMouseState.LeftButton == ButtonState.Pressed) && (lastMouseState.X != currentMouseState.X ||
                                                                       lastMouseState.Y != currentMouseState.Y))
            {
                float xMove = lastMouseState.X - currentMouseState.X;
                float yMove = lastMouseState.Y - currentMouseState.Y;

                CameraTarget += 0.05f * (-xMove * CameraRight + yMove * CameraUp);
                forward       = CameraTarget - CameraPos;
                forward.Normalize();

                CameraRight = Vector3.Cross(forward, CameraUp);
                CameraRight.Normalize();
                CameraUp = Vector3.Cross(CameraRight, forward);
                CameraUp.Normalize();

                //CameraUp = new Vector3(0, 1, 0);
                View = Matrix.CreateLookAt(CameraPos, CameraTarget, CameraUp);
            }
            if (currentState.IsKeyDown(Keys.Escape) && lastKeyState.IsKeyUp(Keys.Escape))
            {
                bShowMiku = !bShowMiku;
            }
            //show single chain
            if (currentState.IsKeyDown(Keys.F1) && lastKeyState.IsKeyUp(Keys.F1))
            {
                bShowSingleIkChain = !bShowSingleIkChain;
            }
            if (currentState.IsKeyDown(Keys.PageDown) && lastKeyState.IsKeyUp(Keys.PageDown))
            {
                showSingleChainIndex = (showSingleChainIndex - 1 + miku.IK_Chains.IKChainCount) % miku.IK_Chains.IKChainCount;
            }
            if (currentState.IsKeyDown(Keys.PageUp) && lastKeyState.IsKeyUp(Keys.PageUp))
            {
                showSingleChainIndex = (showSingleChainIndex + 1) % miku.IK_Chains.IKChainCount;
            }

            lastKeyState   = currentState;
            lastMouseState = currentMouseState;
            Font.DrawMessage(showBoneIndex.ToString(), 20, 20);
            #endregion
            base.Update(gameTime);
        }