public Mesh_PrimitiveMode(List <string> imageList)
        {
            UseFigure(imageList, "Indices");
            UseFigure(imageList, "Indices_Points");

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

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

                Runtime.MeshPrimitive meshPrimitive = MeshPrimitive.CreateSinglePlane(includeTextureCoords: false, includeIndices: false);

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

                meshPrimitive.Material = new Runtime.Material
                {
                    MetallicRoughnessMaterial = new Runtime.PbrMetallicRoughness
                    {
                        MetallicFactor = 0
                    },
                };

                // Create the gltf object.
                return(new Model
                {
                    Properties = properties,
                    GLTF = CreateGLTF(() => new Runtime.Scene
                    {
                        Nodes = new List <Runtime.Node>
                        {
                            new Runtime.Node
                            {
                                Mesh = new Runtime.Mesh
                                {
                                    MeshPrimitives = new List <Runtime.MeshPrimitive>
                                    {
                                        meshPrimitive
                                    }
                                },
                            },
                        },
                    }),
                });
            }

            void SetModePoints(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                var pointPositions = new List <Vector3>();
                var cornerPoints   = new List <Vector3>
                {
                    new Vector3(0.5f, -0.5f, 0.0f),
                    new Vector3(-0.5f, -0.5f, 0.0f),
                    new Vector3(-0.5f, 0.5f, 0.0f),
                    new Vector3(0.5f, 0.3f, 0.0f),
                    new Vector3(0.5f, -0.5f, 0.0f)
                };

                for (var corner = 0; corner < 4; corner++)
                {
                    for (float x = 256; x > 0; x--)
                    {
                        Vector3 startPoint     = cornerPoints[corner];
                        Vector3 endPoint       = cornerPoints[corner + 1];
                        float   fractionOfLine = x / 256f;
                        pointPositions.Add(GetPointOnLine(startPoint, endPoint, fractionOfLine));
                    }
                }

                meshPrimitive.Mode      = ModeEnum.POINTS;
                meshPrimitive.Positions = pointPositions;
                properties.Add(new Property(PropertyName.Mode, meshPrimitive.Mode.ToReadmeString()));
            }

            void SetModeLines(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                if (meshPrimitive.Indices == null)
                {
                    meshPrimitive.Positions = new List <Vector3>
                    {
                        new Vector3(0.5f, -0.5f, 0.0f),
                        new Vector3(-0.5f, -0.5f, 0.0f),
                        new Vector3(-0.5f, -0.5f, 0.0f),
                        new Vector3(-0.5f, 0.5f, 0.0f),
                        new Vector3(-0.5f, 0.5f, 0.0f),
                        new Vector3(0.5f, 0.3f, 0.0f),
                        new Vector3(0.5f, 0.3f, 0.0f),
                        new Vector3(0.5f, -0.5f, 0.0f),
                    };
                }
                meshPrimitive.Mode = ModeEnum.LINES;
                properties.Add(new Property(PropertyName.Mode, meshPrimitive.Mode.ToReadmeString()));
            }

            void SetModeLineLoop(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                if (meshPrimitive.Indices == null)
                {
                    meshPrimitive.Positions = new List <Vector3>
                    {
                        new Vector3(0.5f, -0.5f, 0.0f),
                        new Vector3(0.5f, 0.3f, 0.0f),
                        new Vector3(-0.5f, 0.5f, 0.0f),
                        new Vector3(-0.5f, -0.5f, 0.0f),
                    };
                }
                meshPrimitive.Mode = ModeEnum.LINE_LOOP;
                properties.Add(new Property(PropertyName.Mode, meshPrimitive.Mode.ToReadmeString()));
            }

            void SetModeLineStrip(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                if (meshPrimitive.Indices == null)
                {
                    meshPrimitive.Positions = new List <Vector3>
                    {
                        new Vector3(0.5f, -0.5f, 0.0f),
                        new Vector3(0.5f, 0.3f, 0.0f),
                        new Vector3(-0.5f, 0.5f, 0.0f),
                        new Vector3(-0.5f, -0.5f, 0.0f),
                        new Vector3(0.5f, -0.5f, 0.0f),
                    };
                }
                meshPrimitive.Mode = ModeEnum.LINE_STRIP;
                properties.Add(new Property(PropertyName.Mode, meshPrimitive.Mode.ToReadmeString()));
            }

            void SetModeTriangleStrip(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                if (meshPrimitive.Indices == null)
                {
                    meshPrimitive.Positions = new List <Vector3>
                    {
                        new Vector3(0.5f, -0.5f, 0.0f),
                        new Vector3(0.5f, 0.5f, 0.0f),
                        new Vector3(-0.5f, -0.5f, 0.0f),
                        new Vector3(-0.5f, 0.5f, 0.0f),
                    };
                }
                meshPrimitive.Mode = ModeEnum.TRIANGLE_STRIP;
                properties.Add(new Property(PropertyName.Mode, meshPrimitive.Mode.ToReadmeString()));
            }

            void SetModeTriangleFan(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                if (meshPrimitive.Indices == null)
                {
                    meshPrimitive.Positions = new List <Vector3>
                    {
                        new Vector3(0.5f, -0.5f, 0.0f),
                        new Vector3(0.5f, 0.5f, 0.0f),
                        new Vector3(-0.5f, 0.5f, 0.0f),
                        new Vector3(-0.5f, -0.5f, 0.0f),
                    };
                }
                meshPrimitive.Mode = ModeEnum.TRIANGLE_FAN;
                properties.Add(new Property(PropertyName.Mode, meshPrimitive.Mode.ToReadmeString()));
            }

            void SetModeTriangles(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                if (meshPrimitive.Indices == null)
                {
                    meshPrimitive.Positions = new List <Vector3>
                    {
                        new Vector3(-0.5f, -0.5f, 0.0f),
                        new Vector3(0.5f, -0.5f, 0.0f),
                        new Vector3(0.5f, 0.5f, 0.0f),
                        new Vector3(-0.5f, -0.5f, 0.0f),
                        new Vector3(0.5f, 0.5f, 0.0f),
                        new Vector3(-0.5f, 0.5f, 0.0f),
                    };
                }
                meshPrimitive.Mode = ModeEnum.TRIANGLES;
                properties.Add(new Property(PropertyName.Mode, meshPrimitive.Mode.ToReadmeString()));
            }

            void SetIndicesPoints(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                var pointsIndices = new List <int>();

                for (var x = 0; x < meshPrimitive.Positions.Count(); x++)
                {
                    pointsIndices.Add(x);
                }
                meshPrimitive.Indices = pointsIndices;
                properties.Add(new Property(PropertyName.IndicesValues, $"[0 - {meshPrimitive.Positions.Count() - 1}]"));
            }

            void SetIndicesLines(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                meshPrimitive.Positions = GetSinglePlaneNonReversiblePositions();
                meshPrimitive.Indices   = new List <int>
                {
                    0, 3,
                    3, 2,
                    2, 1,
                    1, 0,
                };
                properties.Add(new Property(PropertyName.IndicesValues, meshPrimitive.Indices.ToReadmeString()));
            }

            void SetIndicesLineLoop(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                meshPrimitive.Positions = GetSinglePlaneNonReversiblePositions();
                meshPrimitive.Indices   = new List <int>
                {
                    0, 3, 2, 1,
                };
                properties.Add(new Property(PropertyName.IndicesValues, meshPrimitive.Indices.ToReadmeString()));
            }

            void SetIndicesTriangleFan(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                meshPrimitive.Positions = MeshPrimitive.GetSinglePlanePositions();
                meshPrimitive.Indices   = new List <int>
                {
                    0, 3, 2, 1,
                };
                properties.Add(new Property(PropertyName.IndicesValues, meshPrimitive.Indices.ToReadmeString()));
            }

            void SetIndicesLineStrip(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                meshPrimitive.Positions = GetSinglePlaneNonReversiblePositions();
                meshPrimitive.Indices   = new List <int>
                {
                    0, 3, 2, 1, 0,
                };
                properties.Add(new Property(PropertyName.IndicesValues, meshPrimitive.Indices.ToReadmeString()));
            }

            void SetIndicesTriangleStrip(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                meshPrimitive.Positions = MeshPrimitive.GetSinglePlanePositions();
                meshPrimitive.Indices   = new List <int>
                {
                    0, 3, 1, 2,
                };
                properties.Add(new Property(PropertyName.IndicesValues, meshPrimitive.Indices.ToReadmeString()));
            }

            void SetIndicesTriangles(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                meshPrimitive.Positions = MeshPrimitive.GetSinglePlanePositions();
                meshPrimitive.Indices   = MeshPrimitive.GetSinglePlaneIndices();
                properties.Add(new Property(PropertyName.IndicesValues, meshPrimitive.Indices.ToReadmeString()));
            }

            void SetIndicesComponentTypeInt(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                meshPrimitive.IndexComponentType = IndexComponentTypeEnum.UNSIGNED_INT;
                properties.Add(new Property(PropertyName.IndicesComponentType, meshPrimitive.IndexComponentType.ToReadmeString()));
            }

            void SetIndicesComponentTypeByte(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                meshPrimitive.IndexComponentType = IndexComponentTypeEnum.UNSIGNED_BYTE;
                properties.Add(new Property(PropertyName.IndicesComponentType, meshPrimitive.IndexComponentType.ToReadmeString()));
            }

            void SetIndicesComponentTypeShort(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                meshPrimitive.IndexComponentType = IndexComponentTypeEnum.UNSIGNED_SHORT;
                properties.Add(new Property(PropertyName.IndicesComponentType, meshPrimitive.IndexComponentType.ToReadmeString()));
            }

            Models = new List <Model>
            {
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModePoints(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeLines(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeLineLoop(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeLineStrip(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeTriangleStrip(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeTriangleFan(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeTriangles(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModePoints(properties, meshPrimitive);
                    SetIndicesPoints(properties, meshPrimitive);
                    SetIndicesComponentTypeInt(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeLines(properties, meshPrimitive);
                    SetIndicesLines(properties, meshPrimitive);
                    SetIndicesComponentTypeInt(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeLineLoop(properties, meshPrimitive);
                    SetIndicesLineLoop(properties, meshPrimitive);
                    SetIndicesComponentTypeInt(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeLineStrip(properties, meshPrimitive);
                    SetIndicesLineStrip(properties, meshPrimitive);
                    SetIndicesComponentTypeInt(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeTriangleStrip(properties, meshPrimitive);
                    SetIndicesTriangleStrip(properties, meshPrimitive);
                    SetIndicesComponentTypeInt(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeTriangleFan(properties, meshPrimitive);
                    SetIndicesTriangleFan(properties, meshPrimitive);
                    SetIndicesComponentTypeInt(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeTriangles(properties, meshPrimitive);
                    SetIndicesTriangles(properties, meshPrimitive);
                    SetIndicesComponentTypeInt(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeTriangles(properties, meshPrimitive);
                    SetIndicesTriangles(properties, meshPrimitive);
                    SetIndicesComponentTypeByte(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeTriangles(properties, meshPrimitive);
                    SetIndicesTriangles(properties, meshPrimitive);
                    SetIndicesComponentTypeShort(properties, meshPrimitive);
                }),
            };

            GenerateUsedPropertiesList();
        }
Exemplo n.º 2
0
        public Accessor_Sparse(List <string> imageList)
        {
            var baseColorTextureA = new Texture {
                Source = UseTexture(imageList, "BaseColor_A")
            };
            var baseColorTextureB = new Texture {
                Source = UseTexture(imageList, "BaseColor_B")
            };

            UseFigure(imageList, "SparseAccessor_Input");
            UseFigure(imageList, "SparseAccessor_Output-Translation");

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

            Model CreateModel(Action <List <Property>, Animation, List <Node> > setProperties)
            {
                var properties     = new List <Property>();
                var animated       = true;
                var meshPrimitive0 = MeshPrimitive.CreateSinglePlane();
                var meshPrimitive1 = MeshPrimitive.CreateSinglePlane();

                var nodes = new List <Node>
                {
                    new Node
                    {
                        Mesh = new Runtime.Mesh
                        {
                            MeshPrimitives = new List <Runtime.MeshPrimitive>
                            {
                                meshPrimitive0
                            }
                        }
                    },
                    new Node
                    {
                        Mesh = new Runtime.Mesh
                        {
                            MeshPrimitives = new List <Runtime.MeshPrimitive>
                            {
                                meshPrimitive1
                            }
                        }
                    }
                };

                SetTexture(nodes);
                var animation  = new Animation();
                var animations = new List <Animation>
                {
                    animation
                };

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

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

                // Create the gltf object.
                return(new Model
                {
                    Properties = properties,
                    GLTF = CreateGLTF
                           (
                        () => new Scene
                    {
                        Nodes = nodes
                    },
                        animations: animations
                           ),
                    Animated = animated,
                    Camera = new Manifest.Camera(new Vector3(0.0f, 0.0f, 2.75f))
                });
            }

            var samplerInputLinear = new[]
            {
                0.0f,
                1.0f,
                2.0f,
            };

            var samplerOutputTranslation = new[]
            {
                new Vector3(0.0f, 0.3f, 0.0f),
                new Vector3(0.0f, -0.3f, 0.0f),
                new Vector3(0.0f, 0.3f, 0.0f),
            };

            void SetTexture(List <Node> nodes)
            {
                nodes[0].Mesh.MeshPrimitives.First().Material = new Runtime.Material
                {
                    PbrMetallicRoughness = new PbrMetallicRoughness
                    {
                        BaseColorTexture = new TextureInfo {
                            Texture = baseColorTextureA
                        },
                    }
                };
                nodes[1].Mesh.MeshPrimitives.First().Material = new Runtime.Material
                {
                    PbrMetallicRoughness = new PbrMetallicRoughness
                    {
                        BaseColorTexture = new TextureInfo {
                            Texture = baseColorTextureB
                        }
                    }
                };
            }

            void OffsetPositions(List <Node> nodes)
            {
                // Offsets the positions of the mesh primitives so they don't overlap. This is done because animation translations override node translations.
                nodes[0].Mesh.MeshPrimitives.First().Positions.Values = ((Vector3[])nodes[0].Mesh.MeshPrimitives.First().Positions.Values).Select(position => { return(new Vector3(position.X - 0.6f, position.Y, position.Z)); });
                nodes[1].Mesh.MeshPrimitives.First().Positions.Values = ((Vector3[])nodes[1].Mesh.MeshPrimitives.First().Positions.Values).Select(position => { return(new Vector3(position.X + 0.6f, position.Y, position.Z)); });
            }

            void OffsetNodeTranslations(List <Node> nodes)
            {
                // Gives each node a translation so they don't overlap, but can have the same values for position.
                nodes[0].Translation = new Vector3(-0.6f, 0.0f, 0.0f);
                nodes[1].Translation = new Vector3(0.6f, 0.0f, 0.0f);
            }

            List <AnimationChannel> CreateChannels(List <Node> nodes, AnimationSampler sampler0, AnimationSampler sampler1)
            {
                return(new List <AnimationChannel>
                {
                    new AnimationChannel
                    {
                        Target = new AnimationChannelTarget
                        {
                            Node = nodes[0],
                        },
                        Sampler = sampler0
                    },
                    new AnimationChannel
                    {
                        Target = new AnimationChannelTarget
                        {
                            Node = nodes[1],
                        },
                        Sampler = sampler1
                    },
                });
            }

            void SetAnimationPaths(List <AnimationChannel> channels, AnimationChannelTargetPath path, List <Property> properties)
            {
                foreach (var channel in channels)
                {
                    channel.Target.Path = path;
                }
            }

            Models = new List <Model>
            {
                CreateModel((properties, animation, nodes) =>
                {
                    OffsetPositions(nodes);

                    var sampler0 = new AnimationSampler
                    {
                        Interpolation = AnimationSamplerInterpolation.Linear,
                        Input         = Data.Create(samplerInputLinear),
                        Output        = Data.Create(samplerOutputTranslation),
                    };

                    var sampler1 = new AnimationSampler
                    {
                        Interpolation = AnimationSamplerInterpolation.Linear,
                        Input         = Data.Create(samplerInputLinear, DataSparse.Create
                                                    (
                                                        new Dictionary <int, float>
                        {
                            { 1, 1.5f }
                        }
                                                    )),
                        Output = Data.Create(samplerOutputTranslation),
                    };

                    var channels       = CreateChannels(nodes, sampler0, sampler1);
                    animation.Channels = channels;
                    SetAnimationPaths(channels, AnimationChannelTargetPath.Translation, properties);

                    properties.Add(new Property(PropertyName.SparseAccessor, "Animation Sampler Input"));
                    properties.Add(new Property(PropertyName.Description, "See Figure 1"));
                }),
                CreateModel((properties, animation, nodes) =>
                {
                    OffsetPositions(nodes);

                    var sampler0 = new AnimationSampler
                    {
                        Interpolation = AnimationSamplerInterpolation.Linear,
                        Input         = Data.Create(samplerInputLinear),
                        Output        = Data.Create(samplerOutputTranslation),
                    };

                    var sampler1 = new AnimationSampler
                    {
                        Interpolation = AnimationSamplerInterpolation.Linear,
                        Input         = Data.Create(samplerInputLinear),
                        Output        = Data.Create(samplerOutputTranslation, DataSparse.Create
                                                    (
                                                        new Dictionary <int, Vector3>
                        {
                            { 1, new Vector3(0.0f, 0.2f, 0.0f) },
                        }
                                                    )),
                    };

                    var channels       = CreateChannels(nodes, sampler0, sampler1);
                    animation.Channels = channels;
                    SetAnimationPaths(channels, AnimationChannelTargetPath.Translation, properties);

                    properties.Add(new Property(PropertyName.SparseAccessor, "Animation Sampler Output"));
                    properties.Add(new Property(PropertyName.Description, "See Figure 2"));
                }),
                CreateModel((properties, animation, nodes) =>
                {
                    OffsetNodeTranslations(nodes);

                    nodes[1].Mesh.MeshPrimitives.First().Positions.Values = nodes[0].Mesh.MeshPrimitives.First().Positions.Values;

                    nodes[1].Mesh.MeshPrimitives.First().Positions.Sparse = DataSparse.Create
                                                                            (
                        new Dictionary <int, Vector3>
                    {
                        { 0, new Vector3(0.25f, -0.5f, 0.0f) },
                        { 2, new Vector3(-0.25f, 0.5f, 0.0f) },
                    }
                                                                            );

                    properties.Add(new Property(PropertyName.SparseAccessor, "Positions"));
                    properties.Add(new Property(PropertyName.Description, "Mesh B's sparse accessor overwrites the values of the top left and bottom right vertexes."));
                }),
                CreateModel((properties, animation, nodes) =>
                {
                    // Add extra vertexes that will be used by the sparse accessor.
                    var positions = MeshPrimitive.GetSinglePlanePositions().Concat(new[]
                    {
                        new Vector3(0.25f, -0.5f, 0.0f),
                        new Vector3(-0.25f, 0.5f, 0.0f),
                    });
                    var textureCoords = MeshPrimitive.GetSinglePlaneTexCoords().Concat(new[]
                    {
                        new Vector2(1.0f, 1.0f),
                        new Vector2(0.0f, 0.0f),
                    });
                    foreach (var node in nodes)
                    {
                        node.Mesh.MeshPrimitives.First().Positions.Values  = positions;
                        node.Mesh.MeshPrimitives.First().TexCoords0.Values = textureCoords;
                    }
                    OffsetNodeTranslations(nodes);

                    nodes[1].Mesh.MeshPrimitives.First().Indices.Values = nodes[0].Mesh.MeshPrimitives.First().Indices.Values;

                    nodes[1].Mesh.MeshPrimitives.First().Indices.Sparse = DataSparse.Create
                                                                          (
                        new Dictionary <int, int>
                    {
                        { 1, 4 },
                        { 5, 5 },
                    }
                                                                          );

                    properties.Add(new Property(PropertyName.SparseAccessor, "Mesh Primitive Indices"));
                    properties.Add(new Property(PropertyName.Description, "Both meshes have six vertexes, but only four are used to make the visible mesh. " +
                                                "Mesh B's sparse accessor replaces the indices pointing at the top left and bottom right vertexes with ones pointing at the unused vertexes."));
                }),
            };

            GenerateUsedPropertiesList();
        }
Exemplo n.º 3
0
        public Accessor_SparseType(List <string> imageList)
        {
            var baseColorTextureA = new Texture {
                Source = UseTexture(imageList, "BaseColor_A")
            };
            var baseColorTextureB = new Texture {
                Source = UseTexture(imageList, "BaseColor_B")
            };

            UseFigure(imageList, "SparseAccessor_Input");
            UseFigure(imageList, "SparseAccessor_Output-Rotation");
            UseFigure(imageList, "SparseAccessor_NoBufferView");

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

            Model CreateModel(Action <List <Property>, Animation, List <Node> > setProperties)
            {
                var properties     = new List <Property>();
                var animated       = true;
                var meshPrimitive0 = MeshPrimitive.CreateSinglePlane(includeTextureCoords: false);
                var meshPrimitive1 = MeshPrimitive.CreateSinglePlane(includeTextureCoords: false);

                var nodes = new List <Node>
                {
                    new Node
                    {
                        Mesh = new Runtime.Mesh
                        {
                            MeshPrimitives = new List <Runtime.MeshPrimitive>
                            {
                                meshPrimitive0
                            }
                        }
                    },
                    new Node
                    {
                        Mesh = new Runtime.Mesh
                        {
                            MeshPrimitives = new List <Runtime.MeshPrimitive>
                            {
                                meshPrimitive1
                            }
                        }
                    }
                };

                var animation  = new Animation();
                var animations = new List <Animation>
                {
                    animation
                };

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

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

                // Create the gltf object.
                return(new Model
                {
                    Properties = properties,
                    GLTF = CreateGLTF
                           (
                        () => new Scene
                    {
                        Nodes = nodes
                    },
                        animations: animations
                           ),
                    Animated = animated,
                    Camera = new Manifest.Camera(new Vector3(0.0f, 0.0f, 2.75f))
                });
            }

            var samplerInputLinear = new[]
            {
                0.0f,
                1.0f,
                2.0f,
            };

            var samplerInputSparse = 1.5f;

            var samplerOutputTranslationSparse = new Vector3(0.0f, 0.2f, 0.0f);

            var samplerOutputRotation = new[]
            {
                Quaternion.CreateFromYawPitchRoll(0.0f, FloatMath.ToRadians(-45.0f), 0.0f),
                Quaternion.CreateFromYawPitchRoll(0.0f, FloatMath.ToRadians(45.0f), 0.0f),
                Quaternion.CreateFromYawPitchRoll(0.0f, FloatMath.ToRadians(-45.0f), 0.0f),
            };

            var samplerOutputRotationSparse = Quaternion.CreateFromYawPitchRoll(0.0f, FloatMath.ToRadians(-90.0f), 0.0f);

            List <AnimationChannel> CreateChannels(List <Node> nodes, AnimationSampler sampler0, AnimationSampler sampler1)
            {
                return(new List <AnimationChannel>
                {
                    new AnimationChannel
                    {
                        Target = new AnimationChannelTarget
                        {
                            Node = nodes[0],
                        },
                        Sampler = sampler0
                    },
                    new AnimationChannel
                    {
                        Target = new AnimationChannelTarget
                        {
                            Node = nodes[1],
                        },
                        Sampler = sampler1
                    },
                });
            }

            void SetAnimationPaths(List <AnimationChannel> channels, AnimationChannelTargetPath path, List <Property> properties)
            {
                foreach (var channel in channels)
                {
                    channel.Target.Path = path;
                }
            }

            void OffsetPositions(List <Node> nodes)
            {
                // Offsets the positions of the mesh primitives so they don't overlap. This is done because animation translations override node translations.
                nodes[0].Mesh.MeshPrimitives.First().Positions.Values = nodes[0].Mesh.MeshPrimitives.First().Positions.Values.Select(position => { return(new Vector3(position.X - 0.6f, position.Y, position.Z)); });
                nodes[1].Mesh.MeshPrimitives.First().Positions.Values = nodes[1].Mesh.MeshPrimitives.First().Positions.Values.Select(position => { return(new Vector3(position.X + 0.6f, position.Y, position.Z)); });
            }

            void SetTexture(List <Node> nodes)
            {
                nodes[0].Mesh.MeshPrimitives.First().Material = new Runtime.Material
                {
                    PbrMetallicRoughness = new PbrMetallicRoughness
                    {
                        BaseColorTexture = new TextureInfo {
                            Texture = baseColorTextureA
                        }
                    }
                };
                nodes[1].Mesh.MeshPrimitives.First().Material = new Runtime.Material
                {
                    PbrMetallicRoughness = new PbrMetallicRoughness
                    {
                        BaseColorTexture = new TextureInfo {
                            Texture = baseColorTextureB
                        }
                    }
                };

                nodes[0].Mesh.MeshPrimitives.First().TexCoords0 = Data.Create(MeshPrimitive.GetSinglePlaneTexCoords());
                nodes[1].Mesh.MeshPrimitives.First().TexCoords0 = Data.Create(MeshPrimitive.GetSinglePlaneTexCoords());
            }

            Models = new List <Model>
            {
                CreateModel((properties, animation, nodes) =>
                {
                    SetTexture(nodes);
                    OffsetPositions(nodes);

                    var sampler0 = new AnimationSampler
                    {
                        Interpolation = AnimationSamplerInterpolation.Linear,
                        Input         = Data.Create(samplerInputLinear),
                        Output        = Data.Create(samplerOutputRotation),
                    };

                    var sampler1 = new AnimationSampler
                    {
                        Interpolation = AnimationSamplerInterpolation.Linear,
                        Input         = Data.Create(samplerInputLinear, DataSparse.Create
                                                    (
                                                        DataType.UnsignedByte,
                                                        new Dictionary <int, float>
                        {
                            { 1, samplerInputSparse }
                        }
                                                    )),
                        Output = Data.Create(samplerOutputRotation),
                    };

                    var channels       = CreateChannels(nodes, sampler0, sampler1);
                    animation.Channels = channels;
                    SetAnimationPaths(channels, AnimationChannelTargetPath.Rotation, properties);

                    properties.Add(new Property(PropertyName.SparseAccessor, "Input"));
                    properties.Add(new Property(PropertyName.IndicesType, sampler1.Input.Sparse.IndicesOutputType.ToReadmeString()));
                    properties.Add(new Property(PropertyName.ValueType, sampler1.Input.OutputType.ToReadmeString()));
                    properties.Add(new Property(PropertyName.BufferView, ":white_check_mark:"));
                    properties.Add(new Property(PropertyName.Description, "See Figure 1"));
                }),
                CreateModel((properties, animation, nodes) =>
                {
                    SetTexture(nodes);
                    OffsetPositions(nodes);

                    var sampler0 = new AnimationSampler
                    {
                        Interpolation = AnimationSamplerInterpolation.Linear,
                        Input         = Data.Create(samplerInputLinear),
                        Output        = Data.Create(samplerOutputRotation),
                    };

                    var sampler1 = new AnimationSampler
                    {
                        Interpolation = AnimationSamplerInterpolation.Linear,
                        Input         = Data.Create(samplerInputLinear, DataSparse.Create
                                                    (
                                                        DataType.UnsignedShort,
                                                        new Dictionary <int, float>
                        {
                            { 1, samplerInputSparse }
                        }
                                                    )),
                        Output = Data.Create(samplerOutputRotation),
                    };

                    var channels       = CreateChannels(nodes, sampler0, sampler1);
                    animation.Channels = channels;
                    SetAnimationPaths(channels, AnimationChannelTargetPath.Rotation, properties);

                    properties.Add(new Property(PropertyName.SparseAccessor, "Input"));
                    properties.Add(new Property(PropertyName.IndicesType, sampler1.Input.Sparse.IndicesOutputType.ToReadmeString()));
                    properties.Add(new Property(PropertyName.ValueType, sampler1.Input.OutputType.ToReadmeString()));
                    properties.Add(new Property(PropertyName.BufferView, ":white_check_mark:"));
                    properties.Add(new Property(PropertyName.Description, "See Figure 1"));
                }),
                CreateModel((properties, animation, nodes) =>
                {
                    SetTexture(nodes);
                    OffsetPositions(nodes);

                    var sampler0 = new AnimationSampler
                    {
                        Interpolation = AnimationSamplerInterpolation.Linear,
                        Input         = Data.Create(samplerInputLinear),
                        Output        = Data.Create(samplerOutputRotation),
                    };

                    var sampler1 = new AnimationSampler
                    {
                        Interpolation = AnimationSamplerInterpolation.Linear,
                        Input         = Data.Create(samplerInputLinear, DataSparse.Create
                                                    (
                                                        DataType.UnsignedInt,
                                                        new Dictionary <int, float>
                        {
                            { 1, samplerInputSparse }
                        }
                                                    )),
                        Output = Data.Create(samplerOutputRotation),
                    };

                    var channels       = CreateChannels(nodes, sampler0, sampler1);
                    animation.Channels = channels;
                    SetAnimationPaths(channels, AnimationChannelTargetPath.Rotation, properties);

                    properties.Add(new Property(PropertyName.SparseAccessor, "Input"));
                    properties.Add(new Property(PropertyName.IndicesType, sampler1.Input.Sparse.IndicesOutputType.ToReadmeString()));
                    properties.Add(new Property(PropertyName.ValueType, sampler1.Input.OutputType.ToReadmeString()));
                    properties.Add(new Property(PropertyName.BufferView, ":white_check_mark:"));
                    properties.Add(new Property(PropertyName.Description, "See Figure 1"));
                }),
                CreateModel((properties, animation, nodes) =>
                {
                    SetTexture(nodes);
                    OffsetPositions(nodes);

                    var sampler0 = new AnimationSampler
                    {
                        Interpolation = AnimationSamplerInterpolation.Linear,
                        Input         = Data.Create(samplerInputLinear),
                        Output        = Data.Create(samplerOutputRotation, DataType.NormalizedByte),
                    };

                    var sampler1 = new AnimationSampler
                    {
                        Interpolation = AnimationSamplerInterpolation.Linear,
                        Input         = Data.Create(samplerInputLinear),
                        Output        = Data.Create(samplerOutputRotation, DataType.NormalizedByte, DataSparse.Create
                                                    (
                                                        DataType.UnsignedByte,
                                                        new Dictionary <int, Quaternion>
                        {
                            { 1, samplerOutputRotationSparse }
                        }
                                                    )),
                    };

                    var channels       = CreateChannels(nodes, sampler0, sampler1);
                    animation.Channels = channels;
                    SetAnimationPaths(channels, AnimationChannelTargetPath.Rotation, properties);

                    properties.Add(new Property(PropertyName.SparseAccessor, "Output"));
                    properties.Add(new Property(PropertyName.IndicesType, ((Data <Quaternion>)sampler1.Output).Sparse.IndicesOutputType.ToReadmeString()));
                    properties.Add(new Property(PropertyName.ValueType, sampler1.Output.OutputType.ToReadmeString()));
                    properties.Add(new Property(PropertyName.BufferView, ":white_check_mark:"));
                    properties.Add(new Property(PropertyName.Description, "See Figure 2"));
                }),
                CreateModel((properties, animation, nodes) =>
                {
                    SetTexture(nodes);
                    OffsetPositions(nodes);

                    var sampler0 = new AnimationSampler
                    {
                        Interpolation = AnimationSamplerInterpolation.Linear,
                        Input         = Data.Create(samplerInputLinear),
                        Output        = Data.Create(samplerOutputRotation, DataType.NormalizedShort),
                    };

                    var sampler1 = new AnimationSampler
                    {
                        Interpolation = AnimationSamplerInterpolation.Linear,
                        Input         = Data.Create(samplerInputLinear),
                        Output        = Data.Create(samplerOutputRotation, DataType.NormalizedShort, DataSparse.Create
                                                    (
                                                        DataType.UnsignedByte,
                                                        new Dictionary <int, Quaternion>
                        {
                            { 1, samplerOutputRotationSparse }
                        }
                                                    )),
                    };

                    var channels       = CreateChannels(nodes, sampler0, sampler1);
                    animation.Channels = channels;
                    SetAnimationPaths(channels, AnimationChannelTargetPath.Rotation, properties);

                    properties.Add(new Property(PropertyName.SparseAccessor, "Output"));
                    properties.Add(new Property(PropertyName.IndicesType, ((Data <Quaternion>)sampler1.Output).Sparse.IndicesOutputType.ToReadmeString()));
                    properties.Add(new Property(PropertyName.ValueType, sampler1.Output.OutputType.ToReadmeString()));
                    properties.Add(new Property(PropertyName.BufferView, ":white_check_mark:"));
                    properties.Add(new Property(PropertyName.Description, "See Figure 2"));
                }),
                CreateModel((properties, animation, nodes) =>
                {
                    // Add extra vertexes that will be used by the sparse accessor.
                    SetTexture(nodes);
                    var positions = MeshPrimitive.GetSinglePlanePositions().Concat(new[]
                    {
                        new Vector3(0.25f, -0.5f, 0.0f),
                        new Vector3(-0.25f, 0.5f, 0.0f),
                    });
                    var texCoords = MeshPrimitive.GetSinglePlaneTexCoords().Concat(new[]
                    {
                        new Vector2(1.0f, 1.0f),
                        new Vector2(0.0f, 0.0f),
                    });

                    foreach (var node in nodes)
                    {
                        node.Mesh.MeshPrimitives.First().Positions.Values  = positions;
                        node.Mesh.MeshPrimitives.First().TexCoords0.Values = texCoords;
                    }
                    OffsetPositions(nodes);

                    var meshPrimitiveIndices    = nodes[1].Mesh.MeshPrimitives.First().Indices;
                    meshPrimitiveIndices.Values = nodes[0].Mesh.MeshPrimitives.First().Indices.Values;
                    meshPrimitiveIndices.Sparse = DataSparse.Create
                                                  (
                        DataType.UnsignedByte,
                        new Dictionary <int, int>
                    {
                        { 1, 4 },
                        { 5, 5 },
                    }
                                                  );

                    properties.Add(new Property(PropertyName.SparseAccessor, "Mesh Primitive Indices"));
                    properties.Add(new Property(PropertyName.IndicesType, meshPrimitiveIndices.Sparse.IndicesOutputType.ToReadmeString()));
                    properties.Add(new Property(PropertyName.ValueType, meshPrimitiveIndices.OutputType.ToReadmeString()));
                    properties.Add(new Property(PropertyName.BufferView, ":white_check_mark:"));
                    properties.Add(new Property(PropertyName.Description, "See the description for the Mesh Primitive Indices model in [Accessor_Sparse](../Accessor_Sparse/README.md)."));
                }),
                CreateModel((properties, animation, nodes) =>
                {
                    SetTexture(nodes);
                    nodes.RemoveAt(0);

                    var sampler = new AnimationSampler
                    {
                        Interpolation = AnimationSamplerInterpolation.Linear,
                        Input         = Data.Create(samplerInputLinear),
                        Output        = Data.Create(Enumerable.Repeat(default(Vector3), 3), DataSparse.Create
                                                    (
                                                        DataType.UnsignedByte,
                                                        new Dictionary <int, Vector3>
                        {
                            { 1, samplerOutputTranslationSparse }
                        }
                                                    )),
                    };

                    var channels = new List <AnimationChannel>
                    {
                        new AnimationChannel
                        {
                            Target = new AnimationChannelTarget
                            {
                                Node = nodes[0],
                                Path = AnimationChannelTargetPath.Translation
                            },
                            Sampler = sampler
                        },
                    };
                    animation.Channels = channels;

                    properties.Add(new Property(PropertyName.SparseAccessor, "Output"));
                    properties.Add(new Property(PropertyName.IndicesType, ((Data <Vector3>)sampler.Output).Sparse.IndicesOutputType.ToReadmeString()));
                    properties.Add(new Property(PropertyName.ValueType, ((Data <Vector3>)sampler.Output).OutputType.ToReadmeString()));
                    properties.Add(new Property(PropertyName.BufferView, ""));
                    properties.Add(new Property(PropertyName.Description, "See Figure 3"));
                }),
            };

            GenerateUsedPropertiesList();
        }
Exemplo n.º 4
0
        public Mesh_PrimitiveMode(List <string> imageList)
        {
            UseFigure(imageList, "Indices");
            UseFigure(imageList, "Indices_Points");

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

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

                Runtime.MeshPrimitive meshPrimitive = MeshPrimitive.CreateSinglePlane(includeTextureCoords: false, includeIndices: false);

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

                meshPrimitive.Material = new Runtime.Material
                {
                    PbrMetallicRoughness = new PbrMetallicRoughness
                    {
                        MetallicFactor = 0
                    },
                };

                // Create the gltf object.
                return(new Model
                {
                    Properties = properties,
                    GLTF = CreateGLTF(() => new Scene
                    {
                        Nodes = new List <Node>
                        {
                            new Node
                            {
                                Mesh = new Runtime.Mesh
                                {
                                    MeshPrimitives = new List <Runtime.MeshPrimitive>
                                    {
                                        meshPrimitive
                                    }
                                },
                            },
                        },
                    }),
                });
            }

            void SetModePoints(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                var pointPositions = new List <Vector3>();
                var cornerPoints   = new[]
                {
                    new Vector3(0.5f, -0.5f, 0.0f),
                    new Vector3(-0.5f, -0.5f, 0.0f),
                    new Vector3(-0.5f, 0.5f, 0.0f),
                    new Vector3(0.5f, 0.3f, 0.0f),
                    new Vector3(0.5f, -0.5f, 0.0f)
                };

                for (var corner = 0; corner < 4; corner++)
                {
                    for (float x = 256; x > 0; x--)
                    {
                        Vector3 startPoint     = cornerPoints[corner];
                        Vector3 endPoint       = cornerPoints[corner + 1];
                        float   fractionOfLine = x / 256f;
                        pointPositions.Add(GetPointOnLine(startPoint, endPoint, fractionOfLine));
                    }
                }

                meshPrimitive.Mode      = MeshPrimitiveMode.Points;
                meshPrimitive.Positions = Data.Create(pointPositions);
                properties.Add(new Property(PropertyName.Mode, meshPrimitive.Mode.ToReadmeString()));
            }

            void SetModeLines(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                if (meshPrimitive.Indices == null)
                {
                    meshPrimitive.Positions.Values = new[]
                    {
                        new Vector3(0.5f, -0.5f, 0.0f),
                        new Vector3(-0.5f, -0.5f, 0.0f),
                        new Vector3(-0.5f, -0.5f, 0.0f),
                        new Vector3(-0.5f, 0.5f, 0.0f),
                        new Vector3(-0.5f, 0.5f, 0.0f),
                        new Vector3(0.5f, 0.3f, 0.0f),
                        new Vector3(0.5f, 0.3f, 0.0f),
                        new Vector3(0.5f, -0.5f, 0.0f),
                    };
                }
                meshPrimitive.Mode = MeshPrimitiveMode.Lines;
                properties.Add(new Property(PropertyName.Mode, meshPrimitive.Mode.ToReadmeString()));
            }

            void SetModeLineLoop(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                if (meshPrimitive.Indices == null)
                {
                    meshPrimitive.Positions.Values = new[]
                    {
                        new Vector3(0.5f, -0.5f, 0.0f),
                        new Vector3(0.5f, 0.3f, 0.0f),
                        new Vector3(-0.5f, 0.5f, 0.0f),
                        new Vector3(-0.5f, -0.5f, 0.0f),
                    };
                }
                meshPrimitive.Mode = MeshPrimitiveMode.LineLoop;
                properties.Add(new Property(PropertyName.Mode, meshPrimitive.Mode.ToReadmeString()));
            }

            void SetModeLineStrip(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                if (meshPrimitive.Indices == null)
                {
                    meshPrimitive.Positions.Values = new[]
                    {
                        new Vector3(0.5f, -0.5f, 0.0f),
                        new Vector3(0.5f, 0.3f, 0.0f),
                        new Vector3(-0.5f, 0.5f, 0.0f),
                        new Vector3(-0.5f, -0.5f, 0.0f),
                        new Vector3(0.5f, -0.5f, 0.0f),
                    };
                }
                meshPrimitive.Mode = MeshPrimitiveMode.LineStrip;
                properties.Add(new Property(PropertyName.Mode, meshPrimitive.Mode.ToReadmeString()));
            }

            void SetModeTriangleStrip(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                if (meshPrimitive.Indices == null)
                {
                    meshPrimitive.Positions.Values = new[]
                    {
                        new Vector3(0.5f, -0.5f, 0.0f),
                        new Vector3(0.5f, 0.5f, 0.0f),
                        new Vector3(-0.5f, -0.5f, 0.0f),
                        new Vector3(-0.5f, 0.5f, 0.0f),
                    };
                }
                meshPrimitive.Mode = MeshPrimitiveMode.TriangleStrip;
                properties.Add(new Property(PropertyName.Mode, meshPrimitive.Mode.ToReadmeString()));
            }

            void SetModeTriangleFan(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                if (meshPrimitive.Indices == null)
                {
                    meshPrimitive.Positions.Values = new[]
                    {
                        new Vector3(0.5f, -0.5f, 0.0f),
                        new Vector3(0.5f, 0.5f, 0.0f),
                        new Vector3(-0.5f, 0.5f, 0.0f),
                        new Vector3(-0.5f, -0.5f, 0.0f),
                    };
                }
                meshPrimitive.Mode = MeshPrimitiveMode.TriangleFan;
                properties.Add(new Property(PropertyName.Mode, meshPrimitive.Mode.ToReadmeString()));
            }

            void SetModeTriangles(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                if (meshPrimitive.Indices == null)
                {
                    meshPrimitive.Positions.Values = new[]
                    {
                        new Vector3(-0.5f, -0.5f, 0.0f),
                        new Vector3(0.5f, -0.5f, 0.0f),
                        new Vector3(0.5f, 0.5f, 0.0f),
                        new Vector3(-0.5f, -0.5f, 0.0f),
                        new Vector3(0.5f, 0.5f, 0.0f),
                        new Vector3(-0.5f, 0.5f, 0.0f),
                    };
                }
                meshPrimitive.Mode = MeshPrimitiveMode.Triangles;
                properties.Add(new Property(PropertyName.Mode, meshPrimitive.Mode.ToReadmeString()));
            }

            void SetIndicesPoints(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                var indices = new List <int>();
                var count   = meshPrimitive.Positions.Values.Count();

                for (int index = 0; index < count; index++)
                {
                    indices.Add(index);
                }
                meshPrimitive.Indices = Data.Create(indices);
                properties.Add(new Property(PropertyName.IndicesValues, $"[0 - {count - 1}]"));
            }

            void SetIndicesLines(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                meshPrimitive.Positions.Values = GetSinglePlaneNonReversiblePositions();
                meshPrimitive.Indices          = Data.Create(new[]
                {
                    0, 3,
                    3, 2,
                    2, 1,
                    1, 0,
                });
                properties.Add(new Property(PropertyName.IndicesValues, meshPrimitive.Indices.Values.ToReadmeString()));
            }

            void SetIndicesLineLoop(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                meshPrimitive.Positions.Values = GetSinglePlaneNonReversiblePositions();
                meshPrimitive.Indices          = Data.Create(new[] { 0, 3, 2, 1 });
                properties.Add(new Property(PropertyName.IndicesValues, meshPrimitive.Indices.Values.ToReadmeString()));
            }

            void SetIndicesTriangleFan(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                meshPrimitive.Positions = Data.Create(MeshPrimitive.GetSinglePlanePositions());
                meshPrimitive.Indices   = Data.Create(new[] { 0, 3, 2, 1 });
                properties.Add(new Property(PropertyName.IndicesValues, meshPrimitive.Indices.Values.ToReadmeString()));
            }

            void SetIndicesLineStrip(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                meshPrimitive.Positions.Values = GetSinglePlaneNonReversiblePositions();
                meshPrimitive.Indices          = Data.Create(new[] { 0, 3, 2, 1, 0 });
                properties.Add(new Property(PropertyName.IndicesValues, meshPrimitive.Indices.Values.ToReadmeString()));
            }

            void SetIndicesTriangleStrip(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                meshPrimitive.Positions = Data.Create(MeshPrimitive.GetSinglePlanePositions());
                meshPrimitive.Indices   = Data.Create(new[] { 0, 3, 1, 2 });
                properties.Add(new Property(PropertyName.IndicesValues, meshPrimitive.Indices.Values.ToReadmeString()));
            }

            void SetIndicesTriangles(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                meshPrimitive.Positions = Data.Create(MeshPrimitive.GetSinglePlanePositions());
                meshPrimitive.Indices   = Data.Create(MeshPrimitive.GetSinglePlaneIndices());
                properties.Add(new Property(PropertyName.IndicesValues, meshPrimitive.Indices.Values.ToReadmeString()));
            }

            void SetIndicesComponentTypeInt(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                meshPrimitive.Indices.OutputType = DataType.UnsignedInt;
                properties.Add(new Property(PropertyName.IndicesComponentType, meshPrimitive.Indices.OutputType.ToReadmeString()));
            }

            void SetIndicesComponentTypeByte(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                meshPrimitive.Indices.OutputType = DataType.UnsignedByte;
                properties.Add(new Property(PropertyName.IndicesComponentType, meshPrimitive.Indices.OutputType.ToReadmeString()));
            }

            void SetIndicesComponentTypeShort(List <Property> properties, Runtime.MeshPrimitive meshPrimitive)
            {
                meshPrimitive.Indices.OutputType = DataType.UnsignedShort;
                properties.Add(new Property(PropertyName.IndicesComponentType, meshPrimitive.Indices.OutputType.ToReadmeString()));
            }

            Models = new List <Model>
            {
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModePoints(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeLines(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeLineLoop(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeLineStrip(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeTriangleStrip(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeTriangleFan(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeTriangles(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModePoints(properties, meshPrimitive);
                    SetIndicesPoints(properties, meshPrimitive);
                    SetIndicesComponentTypeInt(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeLines(properties, meshPrimitive);
                    SetIndicesLines(properties, meshPrimitive);
                    SetIndicesComponentTypeInt(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeLineLoop(properties, meshPrimitive);
                    SetIndicesLineLoop(properties, meshPrimitive);
                    SetIndicesComponentTypeInt(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeLineStrip(properties, meshPrimitive);
                    SetIndicesLineStrip(properties, meshPrimitive);
                    SetIndicesComponentTypeInt(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeTriangleStrip(properties, meshPrimitive);
                    SetIndicesTriangleStrip(properties, meshPrimitive);
                    SetIndicesComponentTypeInt(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeTriangleFan(properties, meshPrimitive);
                    SetIndicesTriangleFan(properties, meshPrimitive);
                    SetIndicesComponentTypeInt(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeTriangles(properties, meshPrimitive);
                    SetIndicesTriangles(properties, meshPrimitive);
                    SetIndicesComponentTypeInt(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeTriangles(properties, meshPrimitive);
                    SetIndicesTriangles(properties, meshPrimitive);
                    SetIndicesComponentTypeByte(properties, meshPrimitive);
                }),
                CreateModel((properties, meshPrimitive) =>
                {
                    SetModeTriangles(properties, meshPrimitive);
                    SetIndicesTriangles(properties, meshPrimitive);
                    SetIndicesComponentTypeShort(properties, meshPrimitive);
                }),
            };

            GenerateUsedPropertiesList();
        }