예제 #1
0
            private static List <Runtime.Node> CreateJointsAndWeightsForCommonRoot(Runtime.Node nodePlane)
            {
                Matrix4x4 baseRotation                    = Matrix4x4.CreateFromYawPitchRoll(0.0f, FloatMath.ToRadians(-90.0f), 0.0f);
                Matrix4x4 jointRotation                   = Matrix4x4.CreateFromYawPitchRoll(0.0f, FloatMath.ToRadians(-15.0f), 0.0f);
                var       translationVectorJoint3         = new Vector3(0.1875f, 0.0f, 0.25f);
                var       translationVectorJoint2         = new Vector3(-0.1875f, 0.0f, 0.25f);
                var       translationVectorJoint1         = new Vector3(0.0f, 0.0f, 0.25f);
                var       translationVectorJoint0         = new Vector3(0.0f, -0.25f, 0.0f);
                Matrix4x4 invertedTranslationMatrixJoint3 = Matrix4x4.CreateTranslation(-translationVectorJoint3);
                Matrix4x4 invertedTranslationMatrixJoint2 = Matrix4x4.CreateTranslation(-translationVectorJoint2);

                var matrixJoint1 = jointRotation;

                Matrix4x4.Invert(matrixJoint1, out Matrix4x4 invertedJoint1);

                var matrixJoint0 = Matrix4x4.CreateTranslation(new Vector3(0, 0.0f, -0.25f));

                Matrix4x4.Invert(matrixJoint0, out Matrix4x4 invertedJoint0);

                var nodeJoint3 = new Runtime.Node
                {
                    Name        = "joint3",
                    Rotation    = Quaternion.CreateFromRotationMatrix(jointRotation),
                    Translation = translationVectorJoint3,
                };
                var nodeJoint2 = new Runtime.Node
                {
                    Name        = "joint2",
                    Rotation    = Quaternion.CreateFromRotationMatrix(jointRotation),
                    Translation = translationVectorJoint2,
                };
                var nodeJoint1 = new Runtime.Node
                {
                    Name        = "joint1",
                    Rotation    = Quaternion.CreateFromRotationMatrix(jointRotation),
                    Translation = translationVectorJoint1,
                    Children    = new[]
                    {
                        nodeJoint2,
                        nodeJoint3
                    }
                };
                var nodeJoint0 = new Runtime.Node
                {
                    Name        = "joint0",
                    Rotation    = Quaternion.CreateFromRotationMatrix(baseRotation),
                    Translation = translationVectorJoint0,
                    Children    = new[]
                    {
                        nodeJoint1
                    }
                };

                nodePlane.Skin = new Runtime.Skin
                {
                    Name   = "skinE",
                    Joints = new List <Runtime.Node>
                    {
                        nodeJoint0,
                        nodeJoint1,
                        nodeJoint2,
                        nodeJoint3
                    },
                    InverseBindMatrices = new List <Matrix4x4>
                    {
                        invertedJoint0,
                        invertedJoint1,
                        invertedTranslationMatrixJoint2,
                        invertedTranslationMatrixJoint3
                    }
                };

                // Top four vertexes of each arm have a weight for the relevant joint. Otherwise the vertex has a weight from the root.
                var jointWeights = new List <List <Runtime.JointWeight> >();

                // Base of trunk
                for (var vertexIndex = 0; vertexIndex < 2; vertexIndex++)
                {
                    jointWeights.Add(new List <Runtime.JointWeight>
                    {
                        new Runtime.JointWeight
                        {
                            JointIndex = 0,
                            Weight     = 1,
                        },
                        new Runtime.JointWeight
                        {
                            JointIndex = 1,
                            Weight     = 0,
                        },
                        new Runtime.JointWeight
                        {
                            JointIndex = 2,
                            Weight     = 0,
                        },
                        new Runtime.JointWeight
                        {
                            JointIndex = 3,
                            Weight     = 0,
                        }
                    });
                }
                // Top of trunk
                for (var vertexIndex = 0; vertexIndex < 3; vertexIndex++)
                {
                    jointWeights.Add(new List <Runtime.JointWeight>
                    {
                        new Runtime.JointWeight
                        {
                            JointIndex = 0,
                            Weight     = 0,
                        },
                        new Runtime.JointWeight
                        {
                            JointIndex = 1,
                            Weight     = 1,
                        },
                        new Runtime.JointWeight
                        {
                            JointIndex = 2,
                            Weight     = 0,
                        },
                        new Runtime.JointWeight
                        {
                            JointIndex = 3,
                            Weight     = 0,
                        }
                    });
                }
                // Left arm
                for (var vertexIndex = 0; vertexIndex < 4; vertexIndex++)
                {
                    jointWeights.Add(new List <Runtime.JointWeight>
                    {
                        new Runtime.JointWeight
                        {
                            JointIndex = 0,
                            Weight     = 0,
                        },
                        new Runtime.JointWeight
                        {
                            JointIndex = 1,
                            Weight     = 0,
                        },
                        new Runtime.JointWeight
                        {
                            JointIndex = 2,
                            Weight     = 1,
                        },
                        new Runtime.JointWeight
                        {
                            JointIndex = 3,
                            Weight     = 0,
                        }
                    });
                }
                // Right arm
                for (var vertexIndex = 0; vertexIndex < 4; vertexIndex++)
                {
                    jointWeights.Add(new List <Runtime.JointWeight>
                    {
                        new Runtime.JointWeight
                        {
                            JointIndex = 0,
                            Weight     = 0,
                        },
                        new Runtime.JointWeight
                        {
                            JointIndex = 1,
                            Weight     = 0,
                        },
                        new Runtime.JointWeight
                        {
                            JointIndex = 2,
                            Weight     = 0,
                        },
                        new Runtime.JointWeight
                        {
                            JointIndex = 3,
                            Weight     = 1,
                        }
                    });
                }
                nodePlane.Mesh.MeshPrimitives.First().VertexJointWeights = jointWeights;

                return(new List <Runtime.Node>
                {
                    nodePlane,
                    nodeJoint0
                });
            }
예제 #2
0
            public static List <Runtime.Node> CreatePlaneWithSkinB()
            {
                var colorInner = new Vector4(0.8f, 0.8f, 0.8f, 1.0f);
                var colorOuter = new Vector4(0.0f, 0.0f, 1.0f, 1.0f);

                Matrix4x4 rotation = Matrix4x4.CreateFromYawPitchRoll(0.0f, FloatMath.ToRadians(90.0f), 0.0f);
                var       translationVectorJoint1 = new Vector3(0.0f, 0.0f, -0.6f);
                var       translationVectorJoint0 = new Vector3(0.0f, 0.0f, 0.3f);
                Matrix4x4 matrixJoint1            = Matrix4x4.CreateTranslation(translationVectorJoint1);
                Matrix4x4 matrixJoint0            = Matrix4x4.CreateTranslation(translationVectorJoint0);

                matrixJoint1 = Matrix4x4.Multiply(matrixJoint0, matrixJoint1);
                Matrix4x4.Invert(matrixJoint1, out Matrix4x4 invertedJoint1);
                Matrix4x4.Invert(matrixJoint0, out Matrix4x4 invertedJoint0);

                var nodeJoint1 = new Runtime.Node
                {
                    Name        = "joint1",
                    Translation = translationVectorJoint1,
                };
                var nodeJoint0 = new Runtime.Node
                {
                    Name        = "joint0",
                    Rotation    = Quaternion.CreateFromRotationMatrix(rotation),
                    Translation = new Vector3(0.0f, -0.3f, 0.0f),
                    Children    = new[]
                    {
                        nodeJoint1
                    },
                };

                var jointsList = new List <Runtime.Node>
                {
                    nodeJoint0,
                    nodeJoint1
                };
                var inverseBindMatricesList = new List <Matrix4x4>
                {
                    invertedJoint0,
                    invertedJoint1
                };
                var innerSkin = new Runtime.Skin
                {
                    Joints = jointsList,
                    InverseBindMatrices = inverseBindMatricesList
                };
                var outerSkin = new Runtime.Skin
                {
                    Joints = jointsList,
                    InverseBindMatrices = inverseBindMatricesList
                };

                var nodeInnerPrism = new Runtime.Node
                {
                    Name = "innerPrism",
                    Skin = innerSkin,
                    Mesh = Mesh.CreatePrism(colorInner),
                };

                var nodeOuterPrism = new Runtime.Node
                {
                    Name = "outerPrism",
                    Skin = outerSkin,
                    Mesh = Mesh.CreatePrism(colorOuter, Scale: new Vector3(1.6f, 1.6f, 0.3f)),
                };

                var weightsListInnerPrism = new List <List <Runtime.JointWeight> >();
                var weightsListOuterPrism = new List <List <Runtime.JointWeight> >();

                for (var i = 0; i < 3; i++)
                {
                    var weight = new List <Runtime.JointWeight>
                    {
                        new Runtime.JointWeight
                        {
                            JointIndex = 0,
                            Weight     = 1,
                        },
                        new Runtime.JointWeight
                        {
                            JointIndex = 1,
                            Weight     = 0,
                        },
                    };
                    weightsListInnerPrism.Add(weight);
                    weightsListOuterPrism.Add(weight);
                }
                for (var i = 0; i < 3; i++)
                {
                    var weight = new List <Runtime.JointWeight>
                    {
                        new Runtime.JointWeight
                        {
                            JointIndex = 0,
                            Weight     = 0,
                        },
                        new Runtime.JointWeight
                        {
                            JointIndex = 1,
                            Weight     = 1,
                        },
                    };
                    weightsListInnerPrism.Add(weight);
                    weightsListOuterPrism.Add(weight);
                }
                nodeInnerPrism.Mesh.MeshPrimitives.First().VertexJointWeights = weightsListInnerPrism;
                nodeOuterPrism.Mesh.MeshPrimitives.First().VertexJointWeights = weightsListOuterPrism;

                return(new List <Runtime.Node>
                {
                    nodeInnerPrism,
                    nodeJoint0,
                    nodeOuterPrism
                });
            }
예제 #3
0
            public static List <Runtime.Node> CreateFoldingPlaneSkin(string skinName, int numberOfNodesInJointHierarchy, float numberOfVertexPairs, int?indexOfTransformNode = null, bool rotationJoint1 = true, float vertexVerticalSpacingMultiplier = 1.0f)
            {
                var color              = new Vector4(0.8f, 0.8f, 0.8f, 1.0f);
                var positions          = new List <Vector3>();
                var indices            = new List <int>();
                var vertexHeightOffset = 0.2f * vertexVerticalSpacingMultiplier;

                float startHeight = -((numberOfVertexPairs - 1) * vertexHeightOffset / 2);
                float positionZ   = startHeight;
                var   index1      = 0;
                var   index2      = 1;
                var   index3      = 2;

                // Create positions and indices. Pattern for indices is as follows:
                // 0, 1, 2,
                // 2, 1, 3,
                // 2, 3, 4,
                // 4, 3, 5,
                // 4, 5, 6,
                // 6, 5, 7,
                // 6, 7, 8,
                // 8, 7, 9,
                // 8, 9, 10,
                // 10, 9, 11
                for (var vertexPairIndex = 0; vertexPairIndex < numberOfVertexPairs; vertexPairIndex++)
                {
                    positions.Add(new Vector3(-0.25f, 0.0f, positionZ));
                    positions.Add(new Vector3(0.25f, 0.0f, positionZ));
                    positionZ = positionZ + vertexHeightOffset;

                    if (vertexPairIndex > 0)
                    {
                        indices.Add(index1);
                        indices.Add(index2);
                        indices.Add(index3);
                        indices.Add(index1 + 2);
                        indices.Add(index2);
                        indices.Add(index3 + 1);
                        index1 += 2;
                        index2 += 2;
                        index3 += 2;
                    }
                }

                Matrix4x4  baseRotation            = Matrix4x4.CreateFromYawPitchRoll(0.0f, FloatMath.ToRadians(-90.0f), 0.0f);
                Quaternion jointRotation           = Quaternion.CreateFromRotationMatrix(Matrix4x4.CreateFromYawPitchRoll(0.0f, FloatMath.ToRadians(-30.0f), 0.0f));
                var        translationVector       = new Vector3(0.0f, 0.0f, vertexHeightOffset);
                var        translationVectorJoint0 = new Vector3(0.0f, startHeight, 0.0f);
                var        matrixJoint0            = Matrix4x4.CreateTranslation(new Vector3(0.0f, 0.0f, startHeight));

                Matrix4x4.Invert(matrixJoint0, out Matrix4x4 invertedJoint0);
                Matrix4x4 invertedTranslationMatrix = Matrix4x4.CreateTranslation(-translationVector);

                var jointHierarchyNodes = new List <Runtime.Node>();

                // Create the root node, since it is a special case.
                jointHierarchyNodes.Add(new Runtime.Node
                {
                    Name        = "joint0",
                    Rotation    = Quaternion.CreateFromRotationMatrix(baseRotation),
                    Translation = translationVectorJoint0,
                });
                // Create the child nodes in the joint hierarchy.
                for (int nodeIndex = 1, jointIndex = 1; nodeIndex < numberOfNodesInJointHierarchy; nodeIndex++)
                {
                    string name;
                    if (nodeIndex == indexOfTransformNode)
                    {
                        name = "transformNode";
                    }
                    else
                    {
                        name = $"joint{jointIndex}";
                        jointIndex++;
                    }

                    Quaternion rotationToUse = Quaternion.Identity;
                    if (nodeIndex == 1 && rotationJoint1)
                    {
                        rotationToUse = jointRotation;
                    }

                    jointHierarchyNodes.Add(new Runtime.Node
                    {
                        Name        = name,
                        Rotation    = rotationToUse,
                        Translation = translationVector,
                    });

                    // Add as a child of the previous node.
                    jointHierarchyNodes[nodeIndex - 1].Children = new[] { jointHierarchyNodes[nodeIndex] };
                }

                // Assembles the joints and inverseBindMatrices to create the skin.
                var joints = new List <Runtime.Node>
                {
                    jointHierarchyNodes[0]
                };
                var inverseBindMatrices = new List <Matrix4x4>
                {
                    invertedJoint0
                };

                for (int nodeIndex = 1, translationMultiplier = 1; nodeIndex < numberOfNodesInJointHierarchy; nodeIndex++)
                {
                    if (nodeIndex != indexOfTransformNode)
                    {
                        joints.Add(jointHierarchyNodes[nodeIndex]);
                        inverseBindMatrices.Add(Matrix4x4.CreateTranslation(new Vector3(0.0f, 0.0f, -positions[nodeIndex * 2].Z)));
                    }
                    translationMultiplier--;
                }

                // Assign weights.
                var weights = new List <List <Runtime.JointWeight> >();

                for (int i = 0; i < numberOfVertexPairs; i++)
                {
                    // If there is a transform node, use the joint from the node before it.
                    // Else if there are more vertex pairs than joints, then the last ones use the last joint.
                    // Otherwise, use the joint with the same index as the vertex pair.
                    int jointIndexToUse = i;
                    if (i == indexOfTransformNode)
                    {
                        jointIndexToUse = jointIndexToUse - 1;
                    }
                    else if (i > joints.Count - 1)
                    {
                        jointIndexToUse = joints.Count - 1;
                    }

                    weights.Add(new List <Runtime.JointWeight>
                    {
                        new Runtime.JointWeight
                        {
                            JointIndex = jointIndexToUse,
                            Weight     = 1,
                        },
                    });
                    weights.Add(new List <Runtime.JointWeight>
                    {
                        new Runtime.JointWeight
                        {
                            JointIndex = jointIndexToUse,
                            Weight     = 1,
                        },
                    });
                }

                var nodePlane = new Runtime.Node
                {
                    Name = "plane",
                    Skin = new Runtime.Skin
                    {
                        Name   = skinName,
                        Joints = joints,
                        InverseBindMatrices = inverseBindMatrices
                    },
                    Mesh = new Runtime.Mesh
                    {
                        MeshPrimitives = new[]
                        {
                            new Runtime.MeshPrimitive
                            {
                                VertexJointWeights = weights,
                                Positions          = positions,
                                Indices            = indices,
                                Material           = new Runtime.Material
                                {
                                    DoubleSided = true,
                                    MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness
                                    {
                                        BaseColorFactor = color
                                    }
                                }
                            }
                        }
                    },
                };

                return(new List <Runtime.Node>
                {
                    nodePlane,
                    jointHierarchyNodes[0]
                });
            }
예제 #4
0
            public static List <Runtime.Node> CreatePlaneWithSkinE(bool jointsHaveCommonParent = true)
            {
                var nodePlane = new Runtime.Node
                {
                    Name = "plane",
                    Mesh = new Runtime.Mesh
                    {
                        MeshPrimitives = new[]
                        {
                            new Runtime.MeshPrimitive
                            {
                                Positions = new List <Vector3>
                                {
                                    // Trunk
                                    new Vector3(-0.125f, 0.000f, -0.250f),
                                    new Vector3(0.125f, 0.000f, -0.250f),
                                    new Vector3(-0.125f, 0.000f, 0.000f),
                                    new Vector3(0.125f, 0.000f, 0.000f),

                                    // Root of V split
                                    new Vector3(0.000f, 0.000f, 0.000f),

                                    // Left branch
                                    new Vector3(-0.250f, 0.000f, 0.250f),
                                    new Vector3(-0.125f, 0.000f, 0.250f),
                                    new Vector3(-0.375f, 0.000f, 0.500f),
                                    new Vector3(-0.250f, 0.000f, 0.500f),

                                    // Right branch
                                    new Vector3(0.125f, 0.000f, 0.250f),
                                    new Vector3(0.250f, 0.000f, 0.250f),
                                    new Vector3(0.250f, 0.000f, 0.500f),
                                    new Vector3(0.375f, 0.000f, 0.500f),
                                },
                                Indices = new List <int>
                                {
                                    0, 1, 2,
                                    2, 1, 3,
                                    2, 4, 5,
                                    5, 4, 6,
                                    5, 6, 7,
                                    7, 6, 8,
                                    4, 3, 9,
                                    9, 3, 10,
                                    9, 10, 11,
                                    11, 10, 12,
                                },
                                Material = new Runtime.Material
                                {
                                    DoubleSided = true,
                                    MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness
                                    {
                                        BaseColorFactor = new Vector4(0.8f, 0.8f, 0.8f, 1.0f)
                                    }
                                }
                            }
                        }
                    },
                };

                // Two different ways to setup the joints and weights, where either there is only one parent or there are two parents that have the same child.
                if (jointsHaveCommonParent)
                {
                    return(CreateJointsAndWeightsForCommonRoot(nodePlane));
                }
                else
                {
                    return(CreateJointsAndWeightsForMultipleRoots(nodePlane));
                }
            }
예제 #5
0
            private static List <Runtime.Node> CreateJointsAndWeightsForMultipleRoots(Runtime.Node nodePlane)
            {
                Matrix4x4 baseRotation            = Matrix4x4.CreateFromYawPitchRoll(0.0f, FloatMath.ToRadians(-90.0f), 0.0f);
                Matrix4x4 jointRotation           = Matrix4x4.CreateFromYawPitchRoll(0.0f, FloatMath.ToRadians(-15.0f), 0.0f);
                var       translationVectorJoint3 = new Vector3(0.0f, 0.25f, 0.0f);
                var       translationVectorJoint2 = new Vector3(0.0f, 0.0f, 0.25f);
                var       translationVectorJoint1 = new Vector3(0.1875f, -0.25f, 0.0f);
                var       translationVectorJoint0 = new Vector3(-0.1875f, -0.25f, 0.0f);
                Matrix4x4 invertedJoint3          = Matrix4x4.CreateTranslation(-translationVectorJoint3);
                Matrix4x4 invertedJoint2          = Matrix4x4.CreateTranslation(-translationVectorJoint2);
                Matrix4x4 invertedJoint1          = Matrix4x4.CreateTranslation(new Vector3(-0.1875f, 0.0f, 0.25f));
                Matrix4x4 invertedJoint0          = Matrix4x4.CreateTranslation(new Vector3(0.1875f, 0.0f, 0.25f));

                var nodeJoint3 = new Runtime.Node
                {
                    Name        = "joint3",
                    Rotation    = Quaternion.CreateFromRotationMatrix(jointRotation),
                    Translation = translationVectorJoint3,
                };
                var nodeJoint2 = new Runtime.Node
                {
                    Name        = "joint2",
                    Rotation    = Quaternion.CreateFromRotationMatrix(jointRotation),
                    Translation = translationVectorJoint2,
                    Children    = new[]
                    {
                        nodeJoint3
                    }
                };
                var nodeJoint1 = new Runtime.Node
                {
                    Name        = "joint1",
                    Rotation    = Quaternion.CreateFromRotationMatrix(baseRotation),
                    Translation = translationVectorJoint1,
                    Children    = new[]
                    {
                        nodeJoint2
                    }
                };
                var nodeJoint0 = new Runtime.Node
                {
                    Name        = "joint0",
                    Rotation    = Quaternion.CreateFromRotationMatrix(baseRotation),
                    Translation = translationVectorJoint0,
                    Children    = new[]
                    {
                        nodeJoint2
                    }
                };

                nodePlane.Skin = new Runtime.Skin
                {
                    Name   = "skinE",
                    Joints = new[]
                    {
                        nodeJoint0,
                        nodeJoint1,
                        nodeJoint2,
                        nodeJoint3
                    },
                    InverseBindMatrices = Runtime.Data.Create(new[]
                    {
                        invertedJoint0,
                        invertedJoint1,
                        invertedJoint2,
                        invertedJoint3
                    }),
                };

                // Top four vertexes of each arm have a weight for the relevant joint. Otherwise the vertex has a weight from the root.
                var joints  = new List <Runtime.JointVector>();
                var weights = new List <Runtime.WeightVector>();

                // Base of trunk
                for (var vertexIndex = 0; vertexIndex < 2; vertexIndex++)
                {
                    joints.Add(new Runtime.JointVector(0, 1, 2, 3));
                    weights.Add(new Runtime.WeightVector(0.0f, 0.0f, 0.0f, 1.0f));
                }
                // Top of trunk
                for (var vertexIndex = 0; vertexIndex < 3; vertexIndex++)
                {
                    joints.Add(new Runtime.JointVector(0, 1, 2, 3));
                    weights.Add(new Runtime.WeightVector(0.0f, 0.0f, 1.0f, 0.0f));
                }
                // Left arm
                for (var vertexIndex = 0; vertexIndex < 4; vertexIndex++)
                {
                    joints.Add(new Runtime.JointVector(0, 1, 2, 3));
                    weights.Add(new Runtime.WeightVector(1.0f, 0.0f, 0.0f, 1.0f));
                }
                // Right arm
                for (var vertexIndex = 0; vertexIndex < 4; vertexIndex++)
                {
                    joints.Add(new Runtime.JointVector(0, 1, 2, 3));
                    weights.Add(new Runtime.WeightVector(0.0f, 1.0f, 0.0f, 0.0f));
                }
                nodePlane.Mesh.MeshPrimitives.First().Joints  = Runtime.Data.Create(joints, Runtime.DataType.UnsignedShort);
                nodePlane.Mesh.MeshPrimitives.First().Weights = Runtime.Data.Create(weights);

                return(new List <Runtime.Node>
                {
                    nodePlane,
                    nodeJoint0,
                    nodeJoint1
                });
            }
예제 #6
0
            private static List <Runtime.Node> CreateJointsAndWeightsForMultipleRoots(Runtime.Node nodePlane)
            {
                Matrix4x4 baseRotation            = Matrix4x4.CreateFromYawPitchRoll(0.0f, FloatMath.ConvertDegreesToRadians(-90.0f), 0.0f);
                Matrix4x4 jointRotation           = Matrix4x4.CreateFromYawPitchRoll(0.0f, FloatMath.ConvertDegreesToRadians(-15.0f), 0.0f);
                var       translationVectorJoint3 = new Vector3(0.0f, 0.25f, 0.0f);
                var       translationVectorJoint2 = new Vector3(0.0f, 0.0f, 0.25f);
                var       translationVectorJoint1 = new Vector3(0.1875f, -0.25f, 0.0f);
                var       translationVectorJoint0 = new Vector3(-0.1875f, -0.25f, 0.0f);
                Matrix4x4 invertedJoint3          = Matrix4x4.CreateTranslation(-translationVectorJoint3);
                Matrix4x4 invertedJoint2          = Matrix4x4.CreateTranslation(-translationVectorJoint2);
                Matrix4x4 invertedJoint1          = Matrix4x4.CreateTranslation(new Vector3(-0.1875f, 0.0f, 0.25f));
                Matrix4x4 invertedJoint0          = Matrix4x4.CreateTranslation(new Vector3(0.1875f, 0.0f, 0.25f));

                var nodeJoint3 = new Runtime.Node
                {
                    Name        = "joint3",
                    Rotation    = Quaternion.CreateFromRotationMatrix(jointRotation),
                    Translation = translationVectorJoint3,
                };
                var nodeJoint2 = new Runtime.Node
                {
                    Name        = "joint2",
                    Rotation    = Quaternion.CreateFromRotationMatrix(jointRotation),
                    Translation = translationVectorJoint2,
                    Children    = new[]
                    {
                        nodeJoint3
                    }
                };
                var nodeJoint1 = new Runtime.Node
                {
                    Name        = "joint1",
                    Rotation    = Quaternion.CreateFromRotationMatrix(baseRotation),
                    Translation = translationVectorJoint1,
                    Children    = new[]
                    {
                        nodeJoint2
                    }
                };
                var nodeJoint0 = new Runtime.Node
                {
                    Name        = "joint0",
                    Rotation    = Quaternion.CreateFromRotationMatrix(baseRotation),
                    Translation = translationVectorJoint0,
                    Children    = new[]
                    {
                        nodeJoint2
                    }
                };

                var joint3 = new Runtime.SkinJoint
                             (
                    inverseBindMatrix: invertedJoint3,
                    node: nodeJoint3
                             );
                var joint2 = new Runtime.SkinJoint
                             (
                    inverseBindMatrix: invertedJoint2,
                    node: nodeJoint2
                             );
                var joint1 = new Runtime.SkinJoint
                             (
                    inverseBindMatrix: invertedJoint1,
                    node: nodeJoint1
                             );
                var joint0 = new Runtime.SkinJoint
                             (
                    inverseBindMatrix: invertedJoint0,
                    node: nodeJoint0
                             );

                nodePlane.Skin.SkinJoints = new[]
                {
                    joint0,
                    joint1,
                    joint2,
                    joint3
                };

                // Top four vertexes of each arm have a weight for the relevant joint. Otherwise the vertex has a weight from the root
                var jointWeights = new List <List <Runtime.JointWeight> >();

                // Base of trunk
                for (int vertexIndex = 0; vertexIndex < 2; vertexIndex++)
                {
                    jointWeights.Add(new List <Runtime.JointWeight>()
                    {
                        new Runtime.JointWeight
                        {
                            Joint  = joint0,
                            Weight = 0,
                        },
                        new Runtime.JointWeight
                        {
                            Joint  = joint1,
                            Weight = 0,
                        },
                        new Runtime.JointWeight
                        {
                            Joint  = joint2,
                            Weight = 0,
                        },
                        new Runtime.JointWeight
                        {
                            Joint  = joint3,
                            Weight = 1,
                        }
                    });
                }
                // Top of trunk
                for (int vertexIndex = 0; vertexIndex < 3; vertexIndex++)
                {
                    jointWeights.Add(new List <Runtime.JointWeight>()
                    {
                        new Runtime.JointWeight
                        {
                            Joint  = joint0,
                            Weight = 0,
                        },
                        new Runtime.JointWeight
                        {
                            Joint  = joint1,
                            Weight = 0,
                        },
                        new Runtime.JointWeight
                        {
                            Joint  = joint2,
                            Weight = 1,
                        },
                        new Runtime.JointWeight
                        {
                            Joint  = joint3,
                            Weight = 0,
                        }
                    });
                }
                // Left arm
                for (int vertexIndex = 0; vertexIndex < 4; vertexIndex++)
                {
                    jointWeights.Add(new List <Runtime.JointWeight>()
                    {
                        new Runtime.JointWeight
                        {
                            Joint  = joint0,
                            Weight = 1,
                        },
                        new Runtime.JointWeight
                        {
                            Joint  = joint1,
                            Weight = 0,
                        },
                        new Runtime.JointWeight
                        {
                            Joint  = joint2,
                            Weight = 0,
                        },
                        new Runtime.JointWeight
                        {
                            Joint  = joint3,
                            Weight = 0,
                        }
                    });
                }
                // Right arm
                for (int vertexIndex = 0; vertexIndex < 4; vertexIndex++)
                {
                    jointWeights.Add(new List <Runtime.JointWeight>()
                    {
                        new Runtime.JointWeight
                        {
                            Joint  = joint0,
                            Weight = 0,
                        },
                        new Runtime.JointWeight
                        {
                            Joint  = joint1,
                            Weight = 1,
                        },
                        new Runtime.JointWeight
                        {
                            Joint  = joint2,
                            Weight = 0,
                        },
                        new Runtime.JointWeight
                        {
                            Joint  = joint3,
                            Weight = 0,
                        }
                    });
                }
                nodePlane.Mesh.MeshPrimitives.First().VertexJointWeights = jointWeights;

                return(new List <Runtime.Node>
                {
                    nodePlane,
                    nodeJoint0,
                    nodeJoint1
                });
            }
예제 #7
0
        public Animation_Skin(List <string> imageList)
        {
            UseFigure(imageList, "skinA");
            UseFigure(imageList, "skinB");
            UseFigure(imageList, "skinC");
            UseFigure(imageList, "skinD");
            UseFigure(imageList, "skinE");
            UseFigure(imageList, "skinF");
            var closeCamera   = new Manifest.Camera(new Vector3(0.5f, 0.0f, 0.6f));
            var distantCamera = new Manifest.Camera(new Vector3(1.5f, 0.0f, 1.0f));
            var skinBCamera   = new Manifest.Camera(new Vector3(0.5f, 0.6f, 1.1f));

            // There are no common properties in this model group that are reported in the readme.

            Model CreateModel(Action <List <Property>, List <Runtime.Animation>, List <Runtime.Node> > setProperties, Action <Model> setCamera, Action <glTFLoader.Schema.Gltf> postRuntimeChanges = null)
            {
                var properties = new List <Property>();
                var nodes      = new List <Runtime.Node>();
                var animations = new List <Runtime.Animation>();
                var animated   = true;

                // There are no common properties in this model group.

                // Apply the properties that are specific to this gltf.
                setProperties(properties, animations, nodes);

                // If no animations are used, null out that property.
                if (!animations.Any())
                {
                    animations = null;
                    animated   = false;
                }

                // Create the gltf object.
                var model = new Model
                {
                    Properties = properties,
                    GLTF       = CreateGLTF(() => new Runtime.Scene
                    {
                        Nodes = nodes
                    }, animations: animations),
                    Animated = animated,
                };

                if (postRuntimeChanges != null)
                {
                    model.PostRuntimeChanges = postRuntimeChanges;
                }

                setCamera(model);

                return(model);
            }

            void AddRotationAnimationChannel(List <Runtime.AnimationChannel> channelList, Runtime.Node targetNode, Quaternion pitchValue, Quaternion restValue)
            {
                channelList.Add(
                    new Runtime.AnimationChannel
                {
                    Target = new Runtime.AnimationChannelTarget
                    {
                        Node = targetNode,
                        Path = Runtime.AnimationChannelTarget.PathEnum.ROTATION,
                    },
                    Sampler = new Runtime.LinearAnimationSampler <Quaternion>
                              (
                        new[]
                    {
                        0.0f,
                        1.0f,
                        2.0f,
                    },
                        new[]
                    {
                        restValue,
                        pitchValue,
                        restValue,
                    }
                              )
                });
            }

            Runtime.Animation CreateFoldingAnimation(Runtime.Node jointRootNode, List <Runtime.AnimationChannel> channelList = null)
            {
                if (channelList == null)
                {
                    channelList = new List <Runtime.AnimationChannel>();
                }

                Runtime.Node nodeCheck  = jointRootNode;
                float        pitchValue = FloatMath.ToRadians(-90.0f);
                var          nodeList   = new List <Runtime.Node>
                {
                    jointRootNode,
                };

                while (nodeCheck.Children != null)
                {
                    foreach (var node in nodeCheck.Children)
                    {
                        nodeList.Add(node);
                    }
                    nodeCheck = nodeCheck.Children.First();
                }

                for (var nodeIndex = 1; nodeIndex < nodeList.Count(); nodeIndex++)
                {
                    float rotateValueModifier = 1.0f;
                    if (nodeIndex == 1)
                    {
                        rotateValueModifier = 0.5f;
                    }
                    else if (nodeIndex % 2 == 0)
                    {
                        rotateValueModifier = -1.0f;
                    }
                    AddRotationAnimationChannel(channelList, nodeList[nodeIndex], Quaternion.CreateFromYawPitchRoll(0.0f, pitchValue * rotateValueModifier, 0.0f), Quaternion.Identity);
                }
                return(new Runtime.Animation
                {
                    Channels = channelList
                });
            }

            Models = new List <Model>
            {
                CreateModel((properties, animations, nodes) =>
                {
                    foreach (Runtime.Node node in Nodes.CreateFoldingPlaneSkin("skinA", 2, 3))
                    {
                        nodes.Add(node);
                    }

                    properties.Add(new Property(PropertyName.Description, "`skinA`."));
                }, (model) => { model.Camera = closeCamera; }),
                CreateModel((properties, animations, nodes) =>
                {
                    foreach (Runtime.Node node in Nodes.CreateFoldingPlaneSkin("skinA", 2, 3))
                    {
                        nodes.Add(node);
                    }
                    animations.Add(CreateFoldingAnimation(nodes[1]));

                    properties.Add(new Property(PropertyName.Description, "`skinA` where `joint1` is animating with a rotation."));
                }, (model) => { model.Camera = closeCamera; }),
                CreateModel((properties, animations, nodes) =>
                {
                    var tempNodeList = Nodes.CreateFoldingPlaneSkin("skinA", 2, 3);

                    // Give the skin node a rotation
                    tempNodeList[0].Rotation = Quaternion.CreateFromYawPitchRoll((FloatMath.Pi / 4.0f), 0.0f, 0.0f);

                    // Create a new parent node and give it a rotation
                    tempNodeList[0] = new Runtime.Node
                    {
                        Name     = "jointParent",
                        Rotation = Quaternion.CreateFromYawPitchRoll((FloatMath.Pi / 4.0f), 0.0f, 0.0f),
                        Children = new List <Runtime.Node>
                        {
                            tempNodeList[0]
                        }
                    };

                    foreach (Runtime.Node node in tempNodeList)
                    {
                        nodes.Add(node);
                    }

                    properties.Add(new Property(PropertyName.Description, "`skinA` where the skinned node has a transform and a parent node with a transform. Both transforms should be ignored."));
                }, (model) => { model.Camera = closeCamera; }),
                // Removed Animation_Skin_03 due to a change in the spec that disallows this situation.
                // Left commented out because this will likely be re-added as a negative test in the future.
                // CreateModel((properties, animations, nodes) =>
                //{
                //     foreach (Runtime.Node node in Nodes.CreateFoldingPlaneSkin("skinA", 2, 3))
                //     {
                //         nodes.Add(node);
                //     }

                //     properties.Add(new Property(PropertyName.Description, "`skinA`. The skin joints are not referenced by the scene nodes."));
                // }, (model) => { model.Camera = closeCamera; }, (gltf) => {gltf.Scenes.First().Nodes = new []{0,};}),
                CreateModel((properties, animations, nodes) =>
                {
                    foreach (Runtime.Node node in Nodes.CreateFoldingPlaneSkin("skinA", 2, 3))
                    {
                        nodes.Add(node);
                    }
                    nodes[0].Skin.InverseBindMatrices = new[]
                    {
                        Matrix4x4.Identity,
                        Matrix4x4.Identity
                    };

                    properties.Add(new Property(PropertyName.Description, "`skinA` without inverse bind matrices."));
                }, (model) => { model.Camera = closeCamera; }),
                CreateModel((properties, animations, nodes) =>
                {
                    foreach (Runtime.Node node in Nodes.CreateFoldingPlaneSkin("skinA", 2, 3))
                    {
                        nodes.Add(node);
                    }
                    animations.Add(CreateFoldingAnimation(nodes[1]));

                    // Attach a node with a mesh to the end of the joint hierarchy
                    Runtime.Node nodeCheck = nodes[1];
                    while (nodeCheck.Children != null)
                    {
                        nodeCheck = nodeCheck.Children.First();
                    }

                    nodeCheck.Children = new List <Runtime.Node>
                    {
                        new Runtime.Node
                        {
                            Mesh = Mesh.CreateTriangle()
                        }
                    };

                    properties.Add(new Property(PropertyName.Description, "`skinA` where `joint1` is animated with a rotation and `joint1` has a triangle mesh attached to it."));
                }, (model) => { model.Camera = closeCamera; }),
                CreateModel((properties, animations, nodes) =>
                {
                    foreach (Runtime.Node node in Nodes.CreateFoldingPlaneSkin("skinA", 2, 3))
                    {
                        nodes.Add(node);
                    }

                    // Create a set of positions for the second mesh that are offset from the first mesh.
                    Runtime.MeshPrimitive originalMeshPrimitive = nodes[0].Mesh.MeshPrimitives.First();
                    var offsetPositions = new List <Vector3>();
                    foreach (Vector3 position in originalMeshPrimitive.Positions)
                    {
                        var offsetPosition = position;
                        offsetPosition.X  += 0.6f;
                        offsetPositions.Add(offsetPosition);
                    }

                    // Create a second mesh
                    nodes.Add(new Runtime.Node
                    {
                        Name = "plane2",
                        Skin = nodes[0].Skin,
                        Mesh = new Runtime.Mesh
                        {
                            MeshPrimitives = new[]
                            {
                                new Runtime.MeshPrimitive
                                {
                                    VertexJointWeights = originalMeshPrimitive.VertexJointWeights,
                                    Positions          = offsetPositions,
                                    Indices            = originalMeshPrimitive.Indices,
                                    Material           = new Runtime.Material
                                    {
                                        DoubleSided = true,
                                        MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness
                                        {
                                            BaseColorFactor = new Vector4(0.0f, 0.0f, 1.0f, 1.0f)
                                        }
                                    }
                                }
                            }
                        }
                    });

                    properties.Add(new Property(PropertyName.Description, "`skinA` where there are two meshes sharing a single skin."));
                }, (model) => { model.Camera = distantCamera; }),
                CreateModel((properties, animations, nodes) =>
                {
                    foreach (Runtime.Node node in Nodes.CreateFoldingPlaneSkin("skinA", 2, 3))
                    {
                        nodes.Add(node);
                    }

                    // Make joint1 a root joint
                    nodes.Add(nodes[1].Children.First());
                    nodes[1].Children = null;

                    // Compensate for no longer inheriting from joint0
                    nodes[2].Rotation    = Quaternion.Multiply((Quaternion)nodes[2].Rotation, (Quaternion)nodes[1].Rotation);
                    nodes[2].Translation = null;
                    nodes[0].Skin.InverseBindMatrices = new[]
                    {
                        nodes[0].Skin.InverseBindMatrices.First(),
                        Matrix4x4.Identity
                    };

                    properties.Add(new Property(PropertyName.Description, "`skinA` where `joint1` is a root node and not a child of `joint0`."));
                }, (model) => { model.Camera = closeCamera; }),
                CreateModel((properties, animations, nodes) =>
                {
                    foreach (Runtime.Node node in Nodes.CreatePlaneWithSkinB())
                    {
                        nodes.Add(node);
                    }

                    // Animate the joints
                    Runtime.Node nodeJoint0 = nodes[1];
                    Runtime.Node nodeJoint1 = nodeJoint0.Children.First();
                    var channelList         = new List <Runtime.AnimationChannel>();
                    float rotationValue     = FloatMath.ToRadians(-15.0f);
                    AddRotationAnimationChannel(channelList, nodeJoint1, Quaternion.CreateFromYawPitchRoll(0.0f, 0.0f, rotationValue), Quaternion.CreateFromYawPitchRoll(0.0f, 0.0f, 0.0f));
                    animations.Add(new Runtime.Animation
                    {
                        Channels = channelList
                    });

                    properties.Add(new Property(PropertyName.Description, "`skinB` which is made up of two skins. `joint1` is referenced by both skins and is animating with a rotation."));
                }, (model) => { model.Camera = skinBCamera; }),
                CreateModel((properties, animations, nodes) =>
                {
                    foreach (Runtime.Node node in Nodes.CreateFoldingPlaneSkin("skinC", 5, 5))
                    {
                        nodes.Add(node);
                    }

                    // Rotate each joint node, except the root which already has the desired rotation
                    Runtime.Node nodeCheck = nodes[1].Children.First();
                    float rotationRadian   = FloatMath.ToRadians(-10.0f);
                    Quaternion rotation    = Quaternion.CreateFromYawPitchRoll(0.0f, rotationRadian, 0.0f);
                    nodeCheck.Rotation     = rotation;
                    while (nodeCheck.Children != null)
                    {
                        foreach (var node in nodeCheck.Children)
                        {
                            node.Rotation = rotation;
                        }
                        nodeCheck = nodeCheck.Children.First();
                    }

                    // Rebuild the inverseBindMatrix for each joint (except the root) to work with the new rotation
                    List <Matrix4x4> inverseBindMatrixList = (List <Matrix4x4>)nodes[0].Skin.InverseBindMatrices;
                    for (var i = 1; i < inverseBindMatrixList.Count; i++)
                    {
                        var translationInverseBindMatrix = inverseBindMatrixList[i];
                        Matrix4x4.Invert(Matrix4x4.CreateRotationX(rotationRadian * (i + 1)), out Matrix4x4 invertedRotation);
                        inverseBindMatrixList[i] = Matrix4x4.Multiply(translationInverseBindMatrix, invertedRotation);
                    }

                    properties.Add(new Property(PropertyName.Description, "`skinC` where all of the joints have a local rotation of -10 degrees, except the root which is rotated -90 degrees."));
                }, (model) => { model.Camera = distantCamera; }),
                CreateModel((properties, animations, nodes) =>
                {
                    foreach (Runtime.Node node in Nodes.CreateFoldingPlaneSkin("skinD", 5, 6, 3, false))
                    {
                        nodes.Add(node);
                    }
                    animations.Add(CreateFoldingAnimation(nodes[1]));

                    // Remove animation for the transform node
                    animations[0].Channels = new List <Runtime.AnimationChannel>
                    {
                        animations[0].Channels.First(),
                        animations[0].Channels.ElementAt(1),
                        animations[0].Channels.ElementAt(3),
                    };

                    // Add the mesh to the transform node
                    nodes[1].Children.First().Children.First().Children.First().Mesh = Mesh.CreateTriangle();

                    properties.Add(new Property(PropertyName.Description, "`skinD` where each joint is animating with a rotation. There is a transform node in the joint hierarchy that is not a joint. That node has a mesh attached to it in order to show its location."));
                }, (model) => { model.Camera = distantCamera; }),
                CreateModel((properties, animations, nodes) =>
                {
                    foreach (Runtime.Node node in Nodes.CreatePlaneWithSkinE())
                    {
                        nodes.Add(node);
                    }

                    properties.Add(new Property(PropertyName.Description, "`skinE`."));
                }, (model) => { model.Camera = distantCamera; }),
                // Removing this model for now, since no viewer currently supports models that have >4 jointweights per vertex.
                //CreateModel((properties, animations, nodes) =>
                //{
                //    foreach (Runtime.Node node in Nodes.CreateFoldingPlaneSkin("skinF", 8, 9, vertexVerticalSpacingMultiplier: 0.5f))
                //    {
                //        nodes.Add(node);
                //    }

                //    // Rotate each joint node, except the root which already has the desired rotation
                //    Runtime.Node nodeCheck = nodes[1].Children.First();
                //    float rotationRadian = FloatMath.ConvertDegreesToRadians(-10.0f);
                //    Quaternion rotationQuaternion = Quaternion.CreateFromYawPitchRoll(0.0f, rotationRadian, 0.0f);
                //    nodeCheck.Rotation = rotationQuaternion;
                //    while (nodeCheck.Children != null)
                //    {
                //        foreach (Runtime.Node node in nodeCheck.Children)
                //        {
                //            node.Rotation = rotationQuaternion;
                //        }
                //        nodeCheck = nodeCheck.Children.First();
                //    }

                //    // Rebuild the inverseBindMatrix for each joint (except the root) to work with the new rotation
                //    var skinJointList = (List<Runtime.SkinJoint>)nodes[0].Skin.SkinJoints;
                //    for (var skinJointIndex = 1; skinJointIndex < skinJointList.Count(); skinJointIndex++)
                //    {
                //        Matrix4x4 translationInverseBindMatrix = skinJointList.ElementAt(skinJointIndex).InverseBindMatrix;
                //        Matrix4x4.Invert(Matrix4x4.CreateRotationX(rotationRadian * (skinJointIndex + 1)) , out Matrix4x4 invertedRotation);
                //        skinJointList.ElementAt(skinJointIndex).InverseBindMatrix = Matrix4x4.Multiply(translationInverseBindMatrix, invertedRotation);
                //    }

                //    // Rebuild weights to include every joint instead of just the ones with a weight > 0
                //    var weightList = (List<List<Runtime.JointWeight>>)nodes[0].Mesh.MeshPrimitives.First().VertexJointWeights;
                //    for (var weightIndex = 0; weightIndex < weightList.Count(); weightIndex++)
                //    {
                //        var jointWeight = new List<Runtime.JointWeight>();

                //        for (var skinJointIndex = 0; skinJointIndex < skinJointList.Count; skinJointIndex++)
                //        {
                //            int weightToUse = 0;
                //            // Set the weight to 1 if the skinJoint is at the same level as the vertex.
                //            // Or Set the weight to 1 if the vertex is further out than the last skinjoint and the last skinjoint is being set.
                //            if (skinJointIndex == (weightIndex / 2) || (((weightIndex / 2) > skinJointList.Count - 1) && (skinJointIndex == skinJointList.Count - 1)) )
                //            {
                //                weightToUse = 1;
                //            }

                //            jointWeight.Add(new Runtime.JointWeight
                //            {
                //                Joint = skinJointList[skinJointIndex],
                //                Weight = weightToUse,
                //            });
                //        }

                //        weightList[weightIndex] = jointWeight;
                //    }

                //    properties.Add(new Property(PropertyName.Description, "`skinF`. Each vertex has weights for more than four joints."));
                //}, (model) => { model.Camera = distantCamera; }),
                CreateModel((properties, animations, nodes) =>
                {
                    var skinA1 = Nodes.CreateFoldingPlaneSkin("skinA", 2, 3);
                    var skinA2 = Nodes.CreateFoldingPlaneSkin("skinA", 2, 3);

                    // Set the same mesh on both nodes.
                    skinA2[0].Mesh = skinA1[0].Mesh;

                    // Offset one of the models so they aren't overlapping.
                    Vector3 translation   = skinA2[1].Translation.Value;
                    skinA2[1].Translation = new Vector3(translation.X + 0.6f, translation.Y, translation.Z);

                    foreach (Runtime.Node node in skinA1)
                    {
                        nodes.Add(node);
                    }

                    foreach (Runtime.Node node in skinA2)
                    {
                        nodes.Add(node);
                    }

                    properties.Add(new Property(PropertyName.Description, "Two instances of `skinA` sharing a mesh but with separate skins."));
                }, (model) => { model.Camera = distantCamera; }),
            };

            GenerateUsedPropertiesList();
        }
            public static List <Runtime.Node> CreatePlaneWithSkinB()
            {
                var colorInner = new Vector4(0.8f, 0.8f, 0.8f, 1.0f);
                var colorOuter = new Vector4(0.0f, 0.0f, 1.0f, 1.0f);

                Matrix4x4 rotation = Matrix4x4.CreateFromYawPitchRoll(0.0f, FloatMath.ToRadians(90.0f), 0.0f);
                var       translationVectorJoint1 = new Vector3(0.0f, 0.0f, -0.6f);
                var       translationVectorJoint0 = new Vector3(0.0f, 0.0f, 0.3f);
                Matrix4x4 matrixJoint1            = Matrix4x4.CreateTranslation(translationVectorJoint1);
                Matrix4x4 matrixJoint0            = Matrix4x4.CreateTranslation(translationVectorJoint0);

                matrixJoint1 = Matrix4x4.Multiply(matrixJoint0, matrixJoint1);
                Matrix4x4.Invert(matrixJoint1, out Matrix4x4 invertedJoint1);
                Matrix4x4.Invert(matrixJoint0, out Matrix4x4 invertedJoint0);

                var nodeJoint1 = new Runtime.Node
                {
                    Name        = "joint1",
                    Translation = translationVectorJoint1,
                };
                var nodeJoint0 = new Runtime.Node
                {
                    Name        = "joint0",
                    Rotation    = Quaternion.CreateFromRotationMatrix(rotation),
                    Translation = new Vector3(0.0f, -0.3f, 0.0f),
                    Children    = new[]
                    {
                        nodeJoint1
                    },
                };

                var skinJoints = new[]
                {
                    nodeJoint0,
                    nodeJoint1
                };
                var inverseBindMatrices = Runtime.Data.Create(new List <Matrix4x4>
                {
                    invertedJoint0,
                    invertedJoint1
                });
                var innerSkin = new Runtime.Skin
                {
                    Joints = skinJoints,
                    InverseBindMatrices = inverseBindMatrices
                };
                var outerSkin = new Runtime.Skin
                {
                    Joints = skinJoints,
                    InverseBindMatrices = inverseBindMatrices
                };

                var nodeInnerPrism = new Runtime.Node
                {
                    Name = "innerPrism",
                    Skin = innerSkin,
                    Mesh = Mesh.CreatePrism(colorInner),
                };

                var nodeOuterPrism = new Runtime.Node
                {
                    Name = "outerPrism",
                    Skin = outerSkin,
                    Mesh = Mesh.CreatePrism(colorOuter, scale: new Vector3(1.6f, 1.6f, 0.3f)),
                };

                var joints  = new List <Runtime.JointVector>();
                var weights = new List <Runtime.WeightVector>();

                for (var i = 0; i < 3; i++)
                {
                    joints.Add(new Runtime.JointVector(0, 1));
                    weights.Add(new Runtime.WeightVector(1.0f, 0.0f));
                }
                for (var i = 0; i < 3; i++)
                {
                    joints.Add(new Runtime.JointVector(0, 1));
                    weights.Add(new Runtime.WeightVector(0.0f, 1.0f));
                }
                nodeInnerPrism.Mesh.MeshPrimitives.First().Joints  = Runtime.Data.Create(joints, Runtime.DataType.UnsignedShort);
                nodeInnerPrism.Mesh.MeshPrimitives.First().Weights = Runtime.Data.Create(weights);
                nodeOuterPrism.Mesh.MeshPrimitives.First().Joints  = Runtime.Data.Create(joints, Runtime.DataType.UnsignedShort);
                nodeOuterPrism.Mesh.MeshPrimitives.First().Weights = Runtime.Data.Create(weights);

                return(new List <Runtime.Node>
                {
                    nodeInnerPrism,
                    nodeJoint0,
                    nodeOuterPrism
                });
            }
예제 #9
0
            public static List <Runtime.Node> CreateMultiNode()
            {
                var vertexPositions = new[]
                {
                    new Vector3(2.5f, 2.5f, 2.5f),
                    new Vector3(-2.5f, 2.5f, 2.5f),
                    new Vector3(-2.5f, -2.5f, 2.5f),
                    new Vector3(2.5f, -2.5f, 2.5f),
                    new Vector3(0.0f, 2.5f, 0.0f),
                    new Vector3(-2.5f, 2.5f, 2.5f),
                    new Vector3(2.5f, 2.5f, 2.5f),
                    new Vector3(-2.5f, 2.5f, 0.0f),
                    new Vector3(0.0f, 7.5f, 0.0f),
                    new Vector3(0.0f, 7.5f, -2.5f),
                    new Vector3(-2.5f, 7.5f, 0.0f),
                    new Vector3(-2.5f, 7.5f, -2.5f),
                    new Vector3(2.5f, 2.5f, -2.5f),
                    new Vector3(0.0f, 2.5f, -2.5f),
                    new Vector3(0.0f, 0.0f, -7.5f),
                    new Vector3(-2.5f, 0.0f, -7.5f),
                    new Vector3(-2.5f, 2.5f, -7.5f),
                    new Vector3(0.0f, 2.5f, -7.5f),
                    new Vector3(0.0f, 2.5f, -2.5f),
                    new Vector3(2.5f, 2.5f, -2.5f),
                    new Vector3(0.0f, 0.0f, -2.5f),
                    new Vector3(-2.5f, -2.5f, -2.5f),
                    new Vector3(2.5f, -2.5f, -2.5f),
                    new Vector3(-2.5f, 0.0f, -2.5f),
                    new Vector3(2.5f, -2.5f, 2.5f),
                    new Vector3(-2.5f, -2.5f, 2.5f),
                    new Vector3(-2.5f, -2.5f, -2.5f),
                    new Vector3(2.5f, -2.5f, -2.5f),
                    new Vector3(2.5f, 2.5f, 2.5f),
                    new Vector3(2.5f, -2.5f, 2.5f),
                    new Vector3(2.5f, 2.5f, -2.5f),
                    new Vector3(2.5f, -2.5f, -2.5f),
                    new Vector3(-2.5f, -2.5f, -2.5f),
                    new Vector3(-2.5f, -2.5f, 2.5f),
                    new Vector3(-2.5f, 0.0f, 0.0f),
                    new Vector3(-2.5f, 0.0f, -2.5f),
                    new Vector3(-2.5f, 2.5f, 2.5f),
                    new Vector3(-7.5f, 2.5f, 0.0f),
                    new Vector3(-7.5f, 0.0f, -2.5f),
                    new Vector3(-7.5f, 0.0f, 0.0f),
                    new Vector3(-7.5f, 2.5f, -2.5f),
                    new Vector3(-2.5f, 2.5f, 0.0f),
                    new Vector3(-7.5f, 0.0f, 0.0f),
                    new Vector3(-2.5f, 0.0f, -2.5f),
                    new Vector3(-2.5f, 0.0f, 0.0f),
                    new Vector3(-7.5f, 0.0f, -2.5f),
                    new Vector3(-7.5f, 2.5f, 0.0f),
                    new Vector3(-2.5f, 0.0f, 0.0f),
                    new Vector3(-2.5f, 2.5f, 0.0f),
                    new Vector3(-7.5f, 0.0f, 0.0f),
                    new Vector3(-2.5f, 2.5f, -2.5f),
                    new Vector3(-7.5f, 2.5f, -2.5f),
                    new Vector3(-2.5f, 2.5f, 0.0f),
                    new Vector3(-7.5f, 2.5f, 0.0f),
                    new Vector3(-7.5f, 0.0f, -2.5f),
                    new Vector3(-2.5f, 2.5f, -2.5f),
                    new Vector3(-2.5f, 0.0f, -2.5f),
                    new Vector3(-7.5f, 2.5f, -2.5f),
                    new Vector3(-2.5f, 7.5f, 0.0f),
                    new Vector3(-2.5f, 2.5f, 0.0f),
                    new Vector3(0.0f, 7.5f, 0.0f),
                    new Vector3(0.0f, 2.5f, 0.0f),
                    new Vector3(0.0f, 2.5f, -2.5f),
                    new Vector3(0.0f, 7.5f, -2.5f),
                    new Vector3(0.0f, 2.5f, 0.0f),
                    new Vector3(0.0f, 7.5f, 0.0f),
                    new Vector3(-2.5f, 2.5f, -2.5f),
                    new Vector3(-2.5f, 7.5f, -2.5f),
                    new Vector3(0.0f, 2.5f, -2.5f),
                    new Vector3(0.0f, 7.5f, -2.5f),
                    new Vector3(-2.5f, 7.5f, 0.0f),
                    new Vector3(-2.5f, 2.5f, -2.5f),
                    new Vector3(-2.5f, 2.5f, 0.0f),
                    new Vector3(-2.5f, 7.5f, -2.5f),
                    new Vector3(0.0f, 2.5f, -2.5f),
                    new Vector3(0.0f, 2.5f, -7.5f),
                    new Vector3(-2.5f, 2.5f, -2.5f),
                    new Vector3(-2.5f, 2.5f, -7.5f),
                    new Vector3(0.0f, 0.0f, -2.5f),
                    new Vector3(0.0f, 0.0f, -7.5f),
                    new Vector3(0.0f, 2.5f, -2.5f),
                    new Vector3(0.0f, 2.5f, -7.5f),
                    new Vector3(-2.5f, 0.0f, -2.5f),
                    new Vector3(-2.5f, 0.0f, -7.5f),
                    new Vector3(0.0f, 0.0f, -2.5f),
                    new Vector3(0.0f, 0.0f, -7.5f),
                    new Vector3(-2.5f, 2.5f, -2.5f),
                    new Vector3(-2.5f, 2.5f, -7.5f),
                    new Vector3(-2.5f, 0.0f, -2.5f),
                    new Vector3(-2.5f, 0.0f, -7.5f),
                    new Vector3(3.0f, -1.0f, 3.0f),
                    new Vector3(-7.5f, -1.0f, 7.5f),
                    new Vector3(3.0f, -1.0f, 7.5f),
                    new Vector3(-7.5f, -1.0f, 3.0f),
                    new Vector3(7.5f, -1.0f, 7.5f),
                    new Vector3(7.5f, -1.0f, 3.0f),
                    new Vector3(7.5f, -1.0f, -7.5f),
                    new Vector3(3.0f, -1.0f, -7.5f),
                };

                var textureCoordSets = new[]
                {
                    new[]
                    {
                        new Vector2(0.788554f, 0.205935f),
                        new Vector2(0.584720f, 0.205900f),
                        new Vector2(0.584685f, 0.409734f),
                        new Vector2(0.788519f, 0.409769f),
                        new Vector2(0.471918f, 0.880496f),
                        new Vector2(0.369983f, 0.982396f),
                        new Vector2(0.573817f, 0.982430f),
                        new Vector2(0.370001f, 0.880479f),
                        new Vector2(0.232172f, 0.857846f),
                        new Vector2(0.232064f, 0.959100f),
                        new Vector2(0.333426f, 0.857955f),
                        new Vector2(0.333317f, 0.959208f),
                        new Vector2(0.573852f, 0.778596f),
                        new Vector2(0.471935f, 0.778579f),
                        new Vector2(0.249236f, 0.325688f),
                        new Vector2(0.249140f, 0.426797f),
                        new Vector2(0.350249f, 0.426892f),
                        new Vector2(0.350345f, 0.325783f),
                        new Vector2(0.573870f, 0.676679f),
                        new Vector2(0.573852f, 0.778596f),
                        new Vector2(0.675786f, 0.676697f),
                        new Vector2(0.777721f, 0.574797f),
                        new Vector2(0.777686f, 0.778631f),
                        new Vector2(0.675804f, 0.574780f),
                        new Vector2(0.777652f, 0.982465f),
                        new Vector2(0.981486f, 0.982500f),
                        new Vector2(0.981520f, 0.778666f),
                        new Vector2(0.777686f, 0.778631f),
                        new Vector2(0.573817f, 0.982430f),
                        new Vector2(0.777652f, 0.982465f),
                        new Vector2(0.573852f, 0.778596f),
                        new Vector2(0.777686f, 0.778631f),
                        new Vector2(0.380851f, 0.409699f),
                        new Vector2(0.584685f, 0.409734f),
                        new Vector2(0.482785f, 0.307799f),
                        new Vector2(0.380868f, 0.307782f),
                        new Vector2(0.584720f, 0.205900f),
                        new Vector2(0.225056f, 0.327032f),
                        new Vector2(0.124248f, 0.226196f),
                        new Vector2(0.124234f, 0.327018f),
                        new Vector2(0.225070f, 0.226211f),
                        new Vector2(0.482803f, 0.205882f),
                        new Vector2(0.023427f, 0.226182f),
                        new Vector2(0.124277f, 0.024553f),
                        new Vector2(0.023455f, 0.024539f),
                        new Vector2(0.124248f, 0.226196f),
                        new Vector2(0.325892f, 0.226224f),
                        new Vector2(0.426742f, 0.024595f),
                        new Vector2(0.325920f, 0.024581f),
                        new Vector2(0.426714f, 0.226239f),
                        new Vector2(0.225098f, 0.024567f),
                        new Vector2(0.225070f, 0.226211f),
                        new Vector2(0.325920f, 0.024581f),
                        new Vector2(0.325892f, 0.226224f),
                        new Vector2(0.124248f, 0.226196f),
                        new Vector2(0.225098f, 0.024567f),
                        new Vector2(0.124277f, 0.024553f),
                        new Vector2(0.225070f, 0.226211f),
                        new Vector2(0.333426f, 0.857955f),
                        new Vector2(0.333643f, 0.655447f),
                        new Vector2(0.232172f, 0.857846f),
                        new Vector2(0.232389f, 0.655338f),
                        new Vector2(0.131136f, 0.655230f),
                        new Vector2(0.130919f, 0.857737f),
                        new Vector2(0.232389f, 0.655338f),
                        new Vector2(0.232172f, 0.857846f),
                        new Vector2(0.029882f, 0.655121f),
                        new Vector2(0.029664f, 0.857629f),
                        new Vector2(0.131136f, 0.655230f),
                        new Vector2(0.130919f, 0.857737f),
                        new Vector2(0.333426f, 0.857955f),
                        new Vector2(0.434897f, 0.655555f),
                        new Vector2(0.333643f, 0.655447f),
                        new Vector2(0.434680f, 0.858063f),
                        new Vector2(0.451167f, 0.629205f),
                        new Vector2(0.451358f, 0.426988f),
                        new Vector2(0.350058f, 0.629110f),
                        new Vector2(0.350249f, 0.426892f),
                        new Vector2(0.552276f, 0.629301f),
                        new Vector2(0.552467f, 0.427083f),
                        new Vector2(0.451167f, 0.629205f),
                        new Vector2(0.451358f, 0.426988f),
                        new Vector2(0.248950f, 0.629014f),
                        new Vector2(0.249140f, 0.426797f),
                        new Vector2(0.147841f, 0.628919f),
                        new Vector2(0.148031f, 0.426701f),
                        new Vector2(0.350058f, 0.629110f),
                        new Vector2(0.350249f, 0.426892f),
                        new Vector2(0.248950f, 0.629014f),
                        new Vector2(0.249140f, 0.426797f),
                        new Vector2(0.820246f, 0.187538f),
                        new Vector2(0.979596f, 0.559354f),
                        new Vector2(0.979596f, 0.187538f),
                        new Vector2(0.820247f, 0.559354f),
                        new Vector2(0.979596f, 0.028188f),
                        new Vector2(0.820247f, 0.028188f),
                        new Vector2(0.448431f, 0.028188f),
                        new Vector2(0.448431f, 0.187538f),
                    },
                };

                var indices0 = new[]
                {
                    90, 91, 92,
                    91, 90, 93,
                    94, 95, 92,
                    92, 95, 90,
                    96, 90, 95,
                    90, 96, 97,
                };
                var indices1 = new[]
                {
                    0, 1, 2,
                    0, 2, 3,
                    4, 5, 6,
                    5, 4, 7,
                    8, 9, 10,
                    10, 9, 11,
                    6, 12, 4,
                    4, 12, 13,
                    14, 15, 16,
                    14, 16, 17,
                    18, 19, 20,
                    21, 20, 22,
                    20, 21, 23,
                    20, 19, 22,
                    24, 25, 26,
                    24, 26, 27,
                    28, 29, 30,
                    29, 31, 30,
                    32, 33, 34,
                    32, 34, 35,
                    33, 36, 34,
                    37, 38, 39,
                    38, 37, 40,
                    34, 36, 41,
                    42, 43, 44,
                    43, 42, 45,
                    46, 47, 48,
                    47, 46, 49,
                    50, 51, 52,
                    53, 52, 51,
                    54, 55, 56,
                    55, 54, 57,
                    58, 59, 60,
                    60, 59, 61,
                    62, 63, 64,
                    65, 64, 63,
                    66, 67, 68,
                    68, 67, 69,
                    70, 71, 72,
                    71, 70, 73,
                    74, 75, 76,
                    76, 75, 77,
                    78, 79, 80,
                    80, 79, 81,
                    82, 83, 84,
                    84, 83, 85,
                    86, 87, 88,
                    88, 87, 89,
                };

                var node1 = new Runtime.Node
                {
                    Mesh = new Runtime.Mesh
                    {
                        MeshPrimitives = new[]
                        {
                            new Runtime.MeshPrimitive
                            {
                                Positions        = vertexPositions,
                                TextureCoordSets = textureCoordSets,
                                Indices          = indices1,
                            }
                        }
                    },
                    Name = "Node1"
                };

                var node0 = new Runtime.Node
                {
                    Mesh = new Runtime.Mesh
                    {
                        MeshPrimitives = new[]
                        {
                            new Runtime.MeshPrimitive
                            {
                                Positions        = vertexPositions,
                                TextureCoordSets = textureCoordSets,
                                Indices          = indices0,
                            }
                        }
                    },
                    Name     = "Node0",
                    Children = new[]
                    {
                        node1
                    }
                };

                return(new List <Runtime.Node>
                {
                    node0,
                    node1,
                });
            }
예제 #10
0
        public Animation_Node(List <string> imageList)
        {
            Runtime.Image baseColorTextureImage = UseTexture(imageList, "BaseColor_Cube");

            // There are no common properties in this model group that are reported in the readme.

            Model CreateModel(Action <List <Property>, List <Runtime.AnimationChannel>, Runtime.Node> setProperties)
            {
                var properties        = new List <Property>();
                var cubeMeshPrimitive = MeshPrimitive.CreateCube();

                // Apply the common properties to the gltf.
                cubeMeshPrimitive.Material = new Runtime.Material
                {
                    MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness
                    {
                        BaseColorTexture = new Runtime.Texture {
                            Source = baseColorTextureImage
                        },
                    },
                };
                var channels = new List <Runtime.AnimationChannel>
                {
                    new Runtime.AnimationChannel()
                };
                var node = new Runtime.Node();

                // Apply the properties that are specific to this gltf.
                setProperties(properties, channels, node);

                // Create the gltf object.
                node.Mesh = new Runtime.Mesh
                {
                    MeshPrimitives = new[]
                    {
                        cubeMeshPrimitive
                    }
                };
                Runtime.GLTF gltf = CreateGLTF(() => new Runtime.Scene()
                {
                    Nodes = new[]
                    {
                        node
                    },
                });
                gltf.Animations = new[]
                {
                    new Runtime.Animation
                    {
                        Channels = channels
                    }
                };
                return(new Model
                {
                    Properties = properties,
                    GLTF = gltf,
                    Animated = true,
                });
            }

            void SetTranslationChannelTarget(List <Property> properties, Runtime.AnimationChannel channel, Runtime.Node node)
            {
                channel.Target = new Runtime.AnimationChannelTarget
                {
                    Node = node,
                    Path = Runtime.AnimationChannelTarget.PathEnum.TRANSLATION,
                };
                properties.Add(new Property(PropertyName.Target, "Translation"));
            }

            void SetRotationChannelTarget(List <Property> properties, Runtime.AnimationChannel channel, Runtime.Node node)
            {
                channel.Target = new Runtime.AnimationChannelTarget
                {
                    Node = node,
                    Path = Runtime.AnimationChannelTarget.PathEnum.ROTATION,
                };
                properties.Add(new Property(PropertyName.Target, "Rotation"));
            }

            void SetScaleChannelTarget(List <Property> properties, Runtime.AnimationChannel channel, Runtime.Node node)
            {
                channel.Target = new Runtime.AnimationChannelTarget
                {
                    Node = node,
                    Path = Runtime.AnimationChannelTarget.PathEnum.SCALE,
                };
                properties.Add(new Property(PropertyName.Target, "Scale"));
            }

            void SetLinearSamplerForTranslation(List <Property> properties, Runtime.AnimationChannel channel)
            {
                channel.Sampler = new Runtime.LinearAnimationSampler <Vector3>
                                  (
                    new[]
                {
                    0.0f,
                    1.0f,
                    2.0f,
                },
                    new[]
                {
                    new Vector3(-0.1f, 0.0f, 0.0f),
                    new Vector3(0.1f, 0.0f, 0.0f),
                    new Vector3(-0.1f, 0.0f, 0.0f),
                }
                                  );

                properties.Add(new Property(PropertyName.Interpolation, "Linear"));
            }

            void SetLinearSamplerForScale(List <Property> properties, Runtime.AnimationChannel channel)
            {
                channel.Sampler = new Runtime.LinearAnimationSampler <Vector3>
                                  (
                    new[]
                {
                    0.0f,
                    1.0f,
                    2.0f,
                },
                    new[]
                {
                    new Vector3(0.8f, 0.8f, 0.8f),
                    new Vector3(1.2f, 1.2f, 1.2f),
                    new Vector3(0.8f, 0.8f, 0.8f),
                }
                                  );

                properties.Add(new Property(PropertyName.Interpolation, "Linear"));
            }

            void SetLinearSamplerForRotation(List <Property> properties, Runtime.AnimationChannel channel)
            {
                channel.Sampler = new Runtime.LinearAnimationSampler <Quaternion>
                                  (
                    new[]
                {
                    0.0f,
                    1.0f,
                    2.0f,
                    3.0f,
                    4.0f,
                },
                    new[]
                {
                    Quaternion.CreateFromYawPitchRoll(FloatMath.ToRadians(90.0f), 0.0f, 0.0f),
                    Quaternion.Identity,
                    Quaternion.CreateFromYawPitchRoll(FloatMath.ToRadians(-90.0f), 0.0f, 0.0f),
                    Quaternion.Identity,
                    Quaternion.CreateFromYawPitchRoll(FloatMath.ToRadians(90.0f), 0.0f, 0.0f),
                }
                                  );

                properties.Add(new Property(PropertyName.Interpolation, "Linear"));
            }

            void SetStepSamplerForTranslation(List <Property> properties, Runtime.AnimationChannel channel)
            {
                channel.Sampler = new Runtime.StepAnimationSampler <Vector3>
                                  (
                    new[]
                {
                    0.0f,
                    1.0f,
                    2.0f,
                    3.0f,
                    4.0f,
                },
                    new[]
                {
                    new Vector3(-0.1f, 0.0f, 0.0f),
                    new Vector3(0.0f, 0.0f, 0.0f),
                    new Vector3(0.1f, 0.0f, 0.0f),
                    new Vector3(0.0f, 0.0f, 0.0f),
                    new Vector3(-0.1f, 0.0f, 0.0f),
                }
                                  );

                properties.Add(new Property(PropertyName.Interpolation, "Step"));
            }

            void SetCubicSplineSamplerForTranslation(List <Property> properties, Runtime.AnimationChannel channel)
            {
                channel.Sampler = new Runtime.CubicSplineAnimationSampler <Vector3>
                                  (
                    new[]
                {
                    0.0f,
                    1.0f,
                    2.0f,
                },
                    new[]
                {
                    new Runtime.CubicSplineAnimationSampler <Vector3> .Key
                    {
                        InTangent  = new Vector3(0.0f, 0.0f, 0.0f),
                        Value      = new Vector3(-0.1f, 0.0f, 0.0f),
                        OutTangent = new Vector3(0.0f, 0.0f, 0.0f)
                    },
                    new Runtime.CubicSplineAnimationSampler <Vector3> .Key
                    {
                        InTangent  = new Vector3(0.0f, 0.0f, 0.0f),
                        Value      = new Vector3(0.1f, 0.0f, 0.0f),
                        OutTangent = new Vector3(0.0f, -0.3f, 0.0f)
                    },
                    new Runtime.CubicSplineAnimationSampler <Vector3> .Key
                    {
                        InTangent  = new Vector3(0.0f, 0.0f, 0.0f),
                        Value      = new Vector3(-0.1f, 0.0f, 0.0f),
                        OutTangent = new Vector3(0.0f, 0.0f, 0.0f)
                    }
                }
                                  );

                properties.Add(new Property(PropertyName.Interpolation, "Cubic Spline"));
            }

            void CreateCubicSplineSamplerForRotation(List <Property> properties, Runtime.AnimationChannel channel)
            {
                channel.Sampler = new Runtime.CubicSplineAnimationSampler <Quaternion>
                                  (
                    new[]
                {
                    0.0f,
                    1.0f,
                    2.0f,
                    3.0f,
                    4.0f,
                },
                    new[]
                {
                    new Runtime.CubicSplineAnimationSampler <Quaternion> .Key
                    {
                        InTangent  = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f),
                        Value      = Quaternion.CreateFromYawPitchRoll(FloatMath.ToRadians(90.0f), 0.0f, 0.0f),
                        OutTangent = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f)
                    },
                    new Runtime.CubicSplineAnimationSampler <Quaternion> .Key
                    {
                        InTangent  = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f),
                        Value      = Quaternion.Identity,
                        OutTangent = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f)
                    },
                    new Runtime.CubicSplineAnimationSampler <Quaternion> .Key
                    {
                        InTangent  = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f),
                        Value      = Quaternion.CreateFromYawPitchRoll(FloatMath.ToRadians(-90.0f), 0.0f, 0.0f),
                        OutTangent = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f)
                    },
                    new Runtime.CubicSplineAnimationSampler <Quaternion> .Key
                    {
                        InTangent  = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f),
                        Value      = Quaternion.Identity,
                        OutTangent = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f)
                    },
                    new Runtime.CubicSplineAnimationSampler <Quaternion> .Key
                    {
                        InTangent  = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f),
                        Value      = Quaternion.CreateFromYawPitchRoll(FloatMath.ToRadians(90.0f), 0.0f, 0.0f),
                        OutTangent = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f)
                    },
                }
                                  );
                properties.Add(new Property(PropertyName.Interpolation, "Cubic Spline"));
            }

            Models = new List <Model>
            {
                CreateModel((properties, channels, node) =>
                {
                    SetTranslationChannelTarget(properties, channels[0], node);
                    SetLinearSamplerForTranslation(properties, channels[0]);
                }),
                CreateModel((properties, channels, node) =>
                {
                    SetRotationChannelTarget(properties, channels[0], node);
                    SetLinearSamplerForRotation(properties, channels[0]);
                }),
                CreateModel((properties, channels, node) =>
                {
                    SetScaleChannelTarget(properties, channels[0], node);
                    SetLinearSamplerForScale(properties, channels[0]);
                }),
                CreateModel((properties, channels, node) =>
                {
                    SetTranslationChannelTarget(properties, channels[0], node);
                    SetStepSamplerForTranslation(properties, channels[0]);
                }),
                CreateModel((properties, channels, node) =>
                {
                    SetTranslationChannelTarget(properties, channels[0], node);
                    SetCubicSplineSamplerForTranslation(properties, channels[0]);
                }),
                CreateModel((properties, channels, node) =>
                {
                    SetRotationChannelTarget(properties, channels[0], node);
                    CreateCubicSplineSamplerForRotation(properties, channels[0]);
                }),
            };

            GenerateUsedPropertiesList();
        }
        public Animation_SamplerType(List <string> imageList)
        {
            Runtime.Image baseColorTextureImage = UseTexture(imageList, "BaseColor_Cube");

            CommonProperties.Add(new Property(PropertyName.Target, "Rotation"));
            CommonProperties.Add(new Property(PropertyName.Interpolation, "Linear"));

            Model CreateModel(AnimationSampler.ComponentTypeEnum samplerOutputComponentType, string samplerOutputComponentTypeDisplayValue)
            {
                var properties        = new List <Property>();
                var cubeMeshPrimitive = MeshPrimitive.CreateCube();

                // Apply the common properties to the gltf.
                cubeMeshPrimitive.Material = new Runtime.Material
                {
                    MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness
                    {
                        BaseColorTexture = new Runtime.Texture {
                            Source = baseColorTextureImage
                        },
                    },
                };
                var node = new Runtime.Node
                {
                    Mesh = new Runtime.Mesh
                    {
                        MeshPrimitives = new[]
                        {
                            cubeMeshPrimitive
                        }
                    }
                };
                var channel = new Runtime.AnimationChannel
                {
                    Target = new Runtime.AnimationChannelTarget
                    {
                        Node = node,
                        Path = Runtime.AnimationChannelTarget.PathEnum.ROTATION,
                    },
                    Sampler = new Runtime.LinearAnimationSampler <Quaternion>
                              (
                        new[]
                    {
                        0.0f,
                        1.0f,
                        2.0f,
                        3.0f,
                        4.0f,
                    },
                        new[]
                    {
                        Quaternion.CreateFromYawPitchRoll(FloatMath.ToRadians(90.0f), 0.0f, 0.0f),
                        Quaternion.Identity,
                        Quaternion.CreateFromYawPitchRoll(FloatMath.ToRadians(-90.0f), 0.0f, 0.0f),
                        Quaternion.Identity,
                        Quaternion.CreateFromYawPitchRoll(FloatMath.ToRadians(90.0f), 0.0f, 0.0f),
                    },
                        outputComponentType: samplerOutputComponentType
                              )
                };

                // Apply the properties that are specific to this gltf.
                properties.Add(new Property(PropertyName.SamplerOutputComponentType, samplerOutputComponentTypeDisplayValue));

                // Create the gltf object.
                Runtime.GLTF gltf = CreateGLTF(() => new Runtime.Scene
                {
                    Nodes = new[]
                    {
                        node
                    },
                });
                gltf.Animations = new[]
                {
                    new Runtime.Animation
                    {
                        Channels = new List <Runtime.AnimationChannel>
                        {
                            channel
                        }
                    }
                };
                return(new Model
                {
                    Properties = properties,
                    GLTF = gltf,
                    Animated = true,
                });
            }

            Models = new List <Model>
            {
                CreateModel(AnimationSampler.ComponentTypeEnum.FLOAT, "Float"),
                CreateModel(AnimationSampler.ComponentTypeEnum.NORMALIZED_BYTE, "Byte"),
                CreateModel(AnimationSampler.ComponentTypeEnum.NORMALIZED_SHORT, "Short"),
            };

            GenerateUsedPropertiesList();
        }