コード例 #1
0
        public bool TrySolver()
        {
            ObjectAnimation.curves[AnimatableProperty.PositionX].GetKeyIndex(startFrame, out int firstIndex);
            int firstFrame = ObjectAnimation.curves[AnimatableProperty.PositionX].keys[firstIndex].frame;

            ObjectAnimation.curves[AnimatableProperty.PositionX].GetKeyIndex(endFrame, out int lastIndex);
            int lastFrame = ObjectAnimation.curves[AnimatableProperty.PositionX].keys[lastIndex].frame;

            if (currentFrame < firstFrame)
            {
                return(false);
            }
            if (currentFrame > lastFrame)
            {
                return(false);
            }


            RequiredKeyframeIndices = FindRequiredTangents(firstFrame, lastFrame, ObjectAnimation.GetCurve(AnimatableProperty.PositionX));
            int K = RequiredKeyframeIndices.Count;
            int totalKeyframes = ObjectAnimation.GetCurve(AnimatableProperty.PositionX).keys.Count;
            int n = 6;
            int p = 24 * K;

            double[] theta = GetAllTangents(p, K, RequiredKeyframeIndices);
            double[,] Theta = ColumnArrayToArray(theta);
            State currentState = GetCurrentState(currentFrame);
            State desiredState = new State()
            {
                position          = positionTarget,
                euler_orientation = rotationTarget.eulerAngles,
                time = currentFrame
            };


            double[,] Js   = ds_dtheta(currentFrame, n, p, K, RequiredKeyframeIndices);
            double[,] DT_D = new double[p, p];
            for (int i = 0; i < p; i++)
            {
                DT_D[i, i] = 0d * 0d;
            }

            double[,] Delta_s_prime = new double[6, 1];
            for (int i = 0; i <= 2; i++)
            {
                Delta_s_prime[i, 0] = desiredState.position[i] - currentState.position[i];
            }
            for (int i = 3; i <= 5; i++)
            {
                Delta_s_prime[i, 0] = -Mathf.DeltaAngle(desiredState.euler_orientation[i - 3], currentState.euler_orientation[i - 3]);
            }

            double[,] TT_T = new double[p, p];
            for (int j = 0; j < p; j++)
            {
                TT_T[j, j] = 1d;
                if (j % 4 == 0 || j % 4 == 1)
                {
                    TT_T[j + 2, j] = -1d;
                }
                else
                {
                    TT_T[j - 2, j] = -1d;
                }
            }
            double wm = 100d;
            double wb = tangentEnergy;
            double wd = 1d;

            double[,] Q_opt = Maths.Add(Maths.Add(Maths.Multiply(2d * wm, Maths.Multiply(Maths.Transpose(Js), Js)), Maths.Add(Maths.Multiply(2d * wd, DT_D), Maths.Multiply(2d * wb, TT_T))), Maths.Multiply((double)Mathf.Pow(10, -6), Maths.Identity(p)));

            double[,] B_opt = Maths.Add(Maths.Multiply(-2d * wm, Maths.Multiply(Maths.Transpose(Js), Delta_s_prime)), Maths.Multiply(2d * wb, Maths.Multiply(TT_T, Theta)));
            double[] b_opt = Maths.ArrayToColumnArray(B_opt);

            double[] delta_theta_0 = new double[p];
            double[] delta_theta;
            double[] s = new double[p];
            for (int i = 0; i < p; i++)
            {
                s[i]             = 1d;
                delta_theta_0[i] = 0d;
            }

            alglib.minqpstate  state_opt;
            alglib.minqpreport rep;

            alglib.minqpcreate(p, out state_opt);
            alglib.minqpsetquadraticterm(state_opt, Q_opt);
            alglib.minqpsetlinearterm(state_opt, b_opt);
            alglib.minqpsetstartingpoint(state_opt, delta_theta_0);

            alglib.minqpsetscale(state_opt, s);

            alglib.minqpsetalgobleic(state_opt, 0.0, 0.0, 0.0, 0);
            alglib.minqpoptimize(state_opt);
            alglib.minqpresults(state_opt, out delta_theta, out rep);


            double[] new_theta = new double[p];
            for (int i = 0; i < p; i++)
            {
                new_theta[i] = delta_theta[i] + theta[i];
            }

            for (int i = 0; i < p; i++)
            {
                if (System.Double.IsNaN(delta_theta[i]))
                {
                    return(false);
                }
            }

            for (int i = 0; i < 6; i++)
            {
                AnimatableProperty property = (AnimatableProperty)i;
                Curve curve = ObjectAnimation.curves[property];

                for (int k = 0; k < K; k++)
                {
                    Vector2 inTangent  = new Vector2((float)new_theta[4 * (i * K + k) + 0], (float)new_theta[4 * (i * K + k) + 1]);
                    Vector2 outTangent = new Vector2((float)new_theta[4 * (i * K + k) + 2], (float)new_theta[4 * (i * K + k) + 3]);
                    ModifyTangents(curve, RequiredKeyframeIndices[k], inTangent, outTangent);
                }
            }
            return(true);
        }
コード例 #2
0
 double[,] ds_dtheta(int frame, int n, int p, int K, List <int> requiredKeyframes)
 {
     double[,] Js1 = ds_dc(frame, n);
     double[,] Js2 = dc_dtheta(frame, n, p, K, requiredKeyframes);
     return(Maths.Multiply(Js1, Js2));
 }
コード例 #3
0
        private IEnumerator ImportHierarchy(Assimp.Node node, Transform parent, GameObject go)
        {
            if (parent != null && parent != go.transform)
            {
                go.transform.parent = parent;
            }

            GlobalState.Instance.messageBox.ShowMessage("Importing Hierarchy : " + importCount);
            // Do not use Assimp Decompose function, it does not work properly
            // use unity decomposition instead
            Matrix4x4 mat = new Matrix4x4(
                new Vector4(node.Transform.A1, node.Transform.B1, node.Transform.C1, node.Transform.D1),
                new Vector4(node.Transform.A2, node.Transform.B2, node.Transform.C2, node.Transform.D2),
                new Vector4(node.Transform.A3, node.Transform.B3, node.Transform.C3, node.Transform.D3),
                new Vector4(node.Transform.A4, node.Transform.B4, node.Transform.C4, node.Transform.D4)
                );
            Vector3    position, scale;
            Quaternion rotation;

            Maths.DecomposeMatrix(mat, out position, out rotation, out scale);

            node.Transform.Decompose(out Assimp.Vector3D scale1, out Assimp.Quaternion rot, out Assimp.Vector3D trans);

            AssignMeshes(node, go);

            if (node.Parent != null)
            {
                go.transform.localPosition = position;
                go.transform.localRotation = rotation;
                go.transform.localScale    = scale;
                go.name = isHuman ? node.Name : Utils.CreateUniqueName(node.Name);
                if (isHuman)
                {
                    if (bones.ContainsKey(node.Name))
                    {
                        bones[node.Name] = go.transform;
                    }
                    if (node.Name.Contains("Hips"))
                    {
                        rootBone = go.transform;
                    }
                }
            }


            if (scene.HasAnimations)
            {
                ImportAnimation(node, go, Quaternion.identity);
            }

            importCount++;
            foreach (Assimp.Node assimpChild in node.Children)
            {
                GameObject child = new GameObject();
                if (blocking)
                {
                    ImportHierarchy(assimpChild, go.transform, child).MoveNext();
                }
                else
                {
                    yield return(StartCoroutine(ImportHierarchy(assimpChild, go.transform, child)));
                }
            }
        }
コード例 #4
0
 public void SetObjectMatrix(GameObject gobject, Matrix4x4 matrix)
 {
     Maths.DecomposeMatrix(matrix, out Vector3 position, out Quaternion rotation, out Vector3 scale);
     SetObjectTransform(gobject, position, rotation, scale);
 }
コード例 #5
0
        private IEnumerator ImportHierarchy(Assimp.Node node, Transform parent, GameObject go, Matrix4x4 cumulMatrix, Quaternion preRotation)
        {
            if (parent != null && parent != go.transform)
            {
                go.transform.parent = parent;
            }

            GlobalState.Instance.messageBox.ShowMessage("Importing Hierarchy : " + importCount);
            // Do not use Assimp Decompose function, it does not work properly
            // use unity decomposition instead
            Matrix4x4 nodeMatrix = new Matrix4x4(
                new Vector4(node.Transform.A1, node.Transform.B1, node.Transform.C1, node.Transform.D1),
                new Vector4(node.Transform.A2, node.Transform.B2, node.Transform.C2, node.Transform.D2),
                new Vector4(node.Transform.A3, node.Transform.B3, node.Transform.C3, node.Transform.D3),
                new Vector4(node.Transform.A4, node.Transform.B4, node.Transform.C4, node.Transform.D4)
                );

            Maths.DecomposeMatrix(nodeMatrix, out Vector3 nodePosition, out Quaternion nodeRotation, out Vector3 nodeScale);
            Maths.DecomposeMatrix(cumulMatrix, out Vector3 cumulPosition, out Quaternion cumulRotation, out Vector3 cumulScale);

            if (node.Name.Contains("$AssimpFbx$") && node.HasChildren)
            {
                if (node.Name.Contains("Translation"))
                {
                    nodePosition = cumulRotation * nodePosition;
                }
                else
                {
                    nodePosition += cumulPosition;
                }
                if (node.Name.Contains("PreRotation"))
                {
                    preRotation  = nodeRotation;
                    nodeRotation = cumulRotation * nodeRotation;
                }
                else
                {
                    nodeRotation = cumulRotation;
                }
                cumulMatrix = Matrix4x4.TRS(nodePosition, nodeRotation, nodeScale);
                if (blocking)
                {
                    ImportHierarchy(node.Children[0], parent, go, cumulMatrix, preRotation).MoveNext();
                }
                else
                {
                    yield return(StartCoroutine(ImportHierarchy(node.Children[0], parent, go, cumulMatrix, preRotation)));
                }
            }
            else
            {
                nodePosition = (cumulRotation * nodePosition) + cumulPosition;
                node.Transform.Decompose(out Assimp.Vector3D scale1, out Assimp.Quaternion rot, out Assimp.Vector3D trans);
                AssignMeshes(node, go);

                if (node.Parent != null)
                {
                    go.transform.localPosition = nodePosition;
                    go.transform.localRotation = nodeRotation;
                    go.transform.localScale    = nodeScale;
                    go.name = isHuman ? node.Name : Utils.CreateUniqueName(node.Name);
                    if (isHuman)
                    {
                        if (bones.ContainsKey(node.Name))
                        {
                            bones[node.Name] = go.transform;
                        }
                        if (node.Name.Contains("Hips"))
                        {
                            rootBone = go.transform;
                        }
                    }
                }


                if (scene.HasAnimations)
                {
                    ImportAnimation(node, go, cumulRotation);
                }

                nodeMatrix = Matrix4x4.TRS(Vector3.zero, cumulRotation * nodeRotation, nodeScale);
                importCount++;
                foreach (Assimp.Node assimpChild in node.Children)
                {
                    GameObject child = new GameObject();
                    if (blocking)
                    {
                        ImportHierarchy(assimpChild, go.transform, child, nodeMatrix, Quaternion.identity).MoveNext();
                    }
                    else
                    {
                        yield return(StartCoroutine(ImportHierarchy(assimpChild, go.transform, child, nodeMatrix, Quaternion.identity)));
                    }
                }
            }
        }