Ejemplo n.º 1
0
        private void brgMeshFormatCheckedListBox_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            if (this.brgObjectsTreeListView.SelectedObject == null ||
                !(this.brgObjectsTreeListView.SelectedObject is BrgMesh))
            {
                return;
            }

            brgMeshFormatCheckedListBox.ItemCheck -= brgMeshFormatCheckedListBox_ItemCheck;

            BrgMesh mesh = (BrgMesh)this.brgObjectsTreeListView.SelectedObject;

            mesh.Header.Format = this.brgMeshFormatCheckedListBox.GetEnum <BrgMeshFormat>();
            if (e.NewValue == CheckState.Checked)
            {
                mesh.Header.Format |= (BrgMeshFormat)this.brgMeshFormatCheckedListBox.Items[e.Index];
            }
            else
            {
                mesh.Header.Format &= ~(BrgMeshFormat)this.brgMeshFormatCheckedListBox.Items[e.Index];
            }

            brg.File.UpdateMeshSettings(mesh.Header.Flags, mesh.Header.Format, mesh.Header.AnimationType, mesh.Header.InterpolationType);
            this.brgMeshFormatCheckedListBox.SetEnum <BrgMeshFormat>(mesh.Header.Format);

            brgMeshFormatCheckedListBox.ItemCheck += brgMeshFormatCheckedListBox_ItemCheck;
        }
Ejemplo n.º 2
0
            private void CreateNormalBuffer(BrgMesh mesh, GltfFormatter formatter, Stream bufferStream)
            {
                long    bufferViewOffset;
                Vector3 max = new Vector3(float.MinValue);
                Vector3 min = new Vector3(float.MaxValue);

                using (BinaryWriter writer = new BinaryWriter(bufferStream, Encoding.UTF8, true))
                {
                    // padding
                    writer.Write(new byte[(-bufferStream.Length) & (PaddingBytes(Accessor.ComponentTypeEnum.FLOAT) - 1)]);
                    bufferViewOffset = bufferStream.Length;

                    foreach (int index in Indices)
                    {
                        Vector3 vec = mesh.Normals[index];
                        vec = vec / vec.Length();

                        max.X = Math.Max(max.X, vec.X);
                        max.Y = Math.Max(max.Y, vec.Y);
                        max.Z = Math.Max(max.Z, vec.Z);

                        min.X = Math.Min(min.X, vec.X);
                        min.Y = Math.Min(min.Y, vec.Y);
                        min.Z = Math.Min(min.Z, vec.Z);

                        writer.Write(vec.X);
                        writer.Write(vec.Y);
                        writer.Write(vec.Z);
                    }
                }

                BufferView posBufferView = new BufferView();

                posBufferView.Buffer     = 0;
                posBufferView.ByteLength = Indices.Count * 12;
                posBufferView.ByteOffset = (int)bufferViewOffset;
                posBufferView.ByteStride = 12;
                posBufferView.Name       = "normalBufferView";
                posBufferView.Target     = BufferView.TargetEnum.ARRAY_BUFFER;

                Accessor posAccessor = new Accessor();

                posAccessor.BufferView    = formatter.bufferViews.Count;
                posAccessor.ByteOffset    = 0;
                posAccessor.ComponentType = Accessor.ComponentTypeEnum.FLOAT;
                posAccessor.Count         = Indices.Count;
                posAccessor.Max           = new[] { max.X, max.Y, max.Z };
                posAccessor.Min           = new[] { min.X, min.Y, min.Z };
                posAccessor.Name          = "normalBufferViewAccessor";
                posAccessor.Type          = Accessor.TypeEnum.VEC3;

                formatter.bufferViews.Add(posBufferView);
                formatter.accessors.Add(posAccessor);
            }
Ejemplo n.º 3
0
            private void CreateIndexBuffer(BrgMesh mesh, GltfFormatter formatter, Stream bufferStream)
            {
                long  bufferViewOffset;
                short faceMin = short.MaxValue;
                short faceMax = short.MinValue;

                using (BinaryWriter writer = new BinaryWriter(bufferStream, Encoding.UTF8, true))
                {
                    // padding
                    writer.Write(new byte[(-bufferStream.Length) & (PaddingBytes(Accessor.ComponentTypeEnum.UNSIGNED_SHORT) - 1)]);
                    bufferViewOffset = bufferStream.Length;

                    foreach (var face in Faces)
                    {
                        faceMin = Math.Min(faceMin, face.Indices[0]);
                        faceMin = Math.Min(faceMin, face.Indices[1]);
                        faceMin = Math.Min(faceMin, face.Indices[2]);

                        faceMax = Math.Max(faceMax, face.Indices[0]);
                        faceMax = Math.Max(faceMax, face.Indices[1]);
                        faceMax = Math.Max(faceMax, face.Indices[2]);

                        writer.Write(face.Indices[0]);
                        writer.Write(face.Indices[1]);
                        writer.Write(face.Indices[2]);
                    }
                }

                BufferView indexBufferView = new BufferView();

                indexBufferView.Buffer     = 0;
                indexBufferView.ByteLength = Faces.Count * 6;
                indexBufferView.ByteOffset = (int)bufferViewOffset;
                indexBufferView.Name       = "indexBufferView";
                indexBufferView.Target     = BufferView.TargetEnum.ELEMENT_ARRAY_BUFFER;

                Accessor indexAccessor = new Accessor();

                indexAccessor.BufferView    = formatter.bufferViews.Count;
                indexAccessor.ByteOffset    = 0;
                indexAccessor.ComponentType = Accessor.ComponentTypeEnum.UNSIGNED_SHORT;
                indexAccessor.Count         = Faces.Count * 3;
                indexAccessor.Max           = new[] { (float)faceMax };
                indexAccessor.Min           = new[] { (float)faceMin };
                indexAccessor.Name          = "indexBufferViewAccessor";
                indexAccessor.Type          = Accessor.TypeEnum.SCALAR;

                formatter.bufferViews.Add(indexBufferView);
                formatter.accessors.Add(indexAccessor);
            }
Ejemplo n.º 4
0
            public void Serialize(MeshPrimitive primitive, BrgMesh mesh, GltfFormatter formatter, Stream bufferStream)
            {
                if (!mesh.Header.Flags.HasFlag(BrgMeshFlag.SECONDARYMESH))
                {
                    primitive.Mode = MeshPrimitive.ModeEnum.TRIANGLES;
                    CreateIndexBuffer(mesh, formatter, bufferStream);
                    primitive.Indices = formatter.accessors.Count - 1;

                    primitive.Attributes = CreateAttributes(mesh, formatter, bufferStream);
                }
                else
                {
                    Targets.Add(CreateAttributes(mesh, formatter, bufferStream));
                }
            }
Ejemplo n.º 5
0
            private Dictionary <string, int> CreateAttributes(BrgMesh mesh, GltfFormatter formatter, Stream bufferStream)
            {
                var attributes = new Dictionary <string, int>();

                CreatePositionBuffer(mesh, formatter, bufferStream);
                int posAccessor = formatter.accessors.Count - 1;

                attributes.Add("POSITION", posAccessor);

                CreateNormalBuffer(mesh, formatter, bufferStream);
                int normAccessor = formatter.accessors.Count - 1;

                attributes.Add("NORMAL", normAccessor);

                return(attributes);
            }
Ejemplo n.º 6
0
        private void brgMeshAnimTypeRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            if (this.brgObjectsTreeListView.SelectedObject == null ||
                !(this.brgObjectsTreeListView.SelectedObject is BrgMesh))
            {
                return;
            }

            keyframeRadioButton.CheckedChanged -= brgMeshAnimTypeRadioButton_CheckedChanged;
            nonuniRadioButton.CheckedChanged   -= brgMeshAnimTypeRadioButton_CheckedChanged;
            skinBoneRadioButton.CheckedChanged -= brgMeshAnimTypeRadioButton_CheckedChanged;

            BrgMesh mesh = (BrgMesh)this.brgObjectsTreeListView.SelectedObject;

            if (this.keyframeRadioButton.Checked)
            {
                mesh.Header.AnimationType = BrgMeshAnimType.KeyFrame;
            }
            else if (this.nonuniRadioButton.Checked)
            {
                mesh.Header.AnimationType = BrgMeshAnimType.NonUniform;
            }
            else if (this.skinBoneRadioButton.Checked)
            {
                mesh.Header.AnimationType = BrgMeshAnimType.SkinBone;
            }

            brg.File.UpdateMeshSettings(mesh.Header.Flags, mesh.Header.Format, mesh.Header.AnimationType, mesh.Header.InterpolationType);

            if (mesh.Header.AnimationType == BrgMeshAnimType.KeyFrame)
            {
                this.keyframeRadioButton.Checked = true;
            }
            else if (mesh.Header.AnimationType == BrgMeshAnimType.NonUniform)
            {
                this.nonuniRadioButton.Checked = true;
            }
            else if (mesh.Header.AnimationType == BrgMeshAnimType.SkinBone)
            {
                this.skinBoneRadioButton.Checked = true;
            }

            keyframeRadioButton.CheckedChanged += brgMeshAnimTypeRadioButton_CheckedChanged;
            nonuniRadioButton.CheckedChanged   += brgMeshAnimTypeRadioButton_CheckedChanged;
            skinBoneRadioButton.CheckedChanged += brgMeshAnimTypeRadioButton_CheckedChanged;
        }
Ejemplo n.º 7
0
        private void brgMeshInterpolationTypeCheckBox_CheckStateChanged(object sender, EventArgs e)
        {
            if (this.brgObjectsTreeListView.SelectedObject == null ||
                !(this.brgObjectsTreeListView.SelectedObject is BrgMesh))
            {
                return;
            }

            interpolationTypeCheckBox.CheckStateChanged -= brgMeshInterpolationTypeCheckBox_CheckStateChanged;

            BrgMesh mesh = (BrgMesh)this.brgObjectsTreeListView.SelectedObject;

            mesh.Header.InterpolationType = (BrgMeshInterpolationType)Convert.ToByte(this.interpolationTypeCheckBox.Checked);
            brg.File.UpdateMeshSettings(mesh.Header.Flags, mesh.Header.Format, mesh.Header.AnimationType, mesh.Header.InterpolationType);
            this.interpolationTypeCheckBox.Checked = Convert.ToBoolean(mesh.Header.InterpolationType);

            interpolationTypeCheckBox.CheckStateChanged += brgMeshInterpolationTypeCheckBox_CheckStateChanged;
        }
Ejemplo n.º 8
0
        public void LoadMeshUI()
        {
            BrgMesh mesh = (BrgMesh)this.Plugin.brgObjectsTreeListView.SelectedObject;

            this.Plugin.interpolationTypeCheckBox.Checked = Convert.ToBoolean(mesh.Header.InterpolationType);
            this.Plugin.brgMeshFlagsCheckedListBox.SetEnum <BrgMeshFlag>(mesh.Header.Flags);
            this.Plugin.brgMeshFormatCheckedListBox.SetEnum <BrgMeshFormat>(mesh.Header.Format);

            if (mesh.Header.AnimationType == BrgMeshAnimType.KeyFrame)
            {
                this.Plugin.keyframeRadioButton.Checked = true;
            }
            else if (mesh.Header.AnimationType == BrgMeshAnimType.NonUniform)
            {
                this.Plugin.nonuniRadioButton.Checked = true;
            }
            else if (mesh.Header.AnimationType == BrgMeshAnimType.SkinBone)
            {
                this.Plugin.skinBoneRadioButton.Checked = true;
            }
        }
Ejemplo n.º 9
0
        public void Import(string fileName)
        {
            // Only need to Update the HEADER, and Animation.Duration, ASETHEADER is auto handled
            this.File = new BrgFile();
            BrgFile           model  = this.File; // just ref here so I don't have to rename model to this.File
            Grendgine_Collada cModel = Grendgine_Collada.Grendgine_Load_File(fileName);

            //Materials
            BrgMaterial mat = new BrgMaterial(model);

            model.Materials.Add(mat);
            mat.AmbientColor     = new Color3D();
            mat.DiffuseColor     = new Color3D();
            mat.SpecularColor    = new Color3D(0.5f);
            mat.SpecularExponent = 5;
            mat.Id      = 100;
            mat.Opacity = 1f;
            mat.Flags  |= BrgMatFlag.HasTexture | BrgMatFlag.SpecularExponent;

            model.Header.NumMaterials = model.Materials.Count();

            //Meshes
            foreach (Grendgine_Collada_Geometry geo in cModel.Library_Geometries.Geometry)
            {
                BrgMesh mesh = new BrgMesh(model);
                model.Meshes.Add(mesh);

                mesh.Header.Flags                     |= BrgMeshFlag.MATERIAL;
                mesh.Header.Flags                     |= model.Meshes.Count == 1 ? 0 : BrgMeshFlag.SECONDARYMESH;
                mesh.Header.AnimationType             |= BrgMeshAnimType.KeyFrame;
                mesh.Header.Format                    |= 0;
                mesh.ExtendedHeader.NumMaterials       = (byte)model.Header.NumMaterials;
                mesh.ExtendedHeader.AnimationLength    = 30;
                mesh.ExtendedHeader.NumUniqueMaterials = 0;

                string polyVertSourceID;
                string polyNormalsSourceID;
                string materialID;
                int[]  vertCountPerPoly;
                int[]  vertLinkPerPoly;
                int[]  vertNormalBindings;

                //Locate the vertices and convert them
                string vertexPosSourceID = geo.Mesh.Vertices.Input.First <Grendgine_Collada_Input_Unshared>(x => x.Semantic == Grendgine_Collada_Input_Semantic.POSITION).source;
                Grendgine_Collada_Float_Array vertsArray = FindSourceByID(geo.Mesh, vertexPosSourceID).Float_Array;

                mesh.Vertices           = FloatToVectorArray(vertsArray);
                mesh.Header.NumVertices = (short)mesh.Vertices.Count;

                //Check for polygons otherwise skip mesh
                if (geo.Mesh.Polylist != null || geo.Mesh.Polylist.Length > 0)
                {
                    mesh.Header.NumFaces = (short)geo.Mesh.Polylist[0].Count;
                    polyVertSourceID     = geo.Mesh.Polylist[0].Input.First <Grendgine_Collada_Input_Unshared>(x => x.Semantic == Grendgine_Collada_Input_Semantic.VERTEX).source;
                    polyNormalsSourceID  = geo.Mesh.Polylist[0].Input.First <Grendgine_Collada_Input_Unshared>(x => x.Semantic == Grendgine_Collada_Input_Semantic.NORMAL).source;
                    vertCountPerPoly     = geo.Mesh.Polylist[0].VCount.Value();
                    materialID           = geo.Mesh.Polylist[0].Material;
                    vertLinkPerPoly      = geo.Mesh.Polylist[0].P.Value();

                    mesh.Faces = new List <Face>(mesh.Header.NumFaces);

                    vertNormalBindings = new int[mesh.Header.NumVertices];

                    int  polyindex = 0;
                    Face ff;
                    foreach (int count in vertCountPerPoly)
                    {
                        if (count == 3) //If triangle
                        {
                            ff         = new Face();
                            ff.Indices = new List <short>(3);
                            ff.Indices.Add((short)vertLinkPerPoly[polyindex]);
                            ff.Indices.Add((short)vertLinkPerPoly[polyindex + 4]);
                            ff.Indices.Add((short)vertLinkPerPoly[polyindex + 2]);
                            //List correct normal bindings
                            vertNormalBindings[ff.Indices[0]] = vertLinkPerPoly[polyindex + 1];
                            vertNormalBindings[ff.Indices[1]] = vertLinkPerPoly[polyindex + 5];
                            vertNormalBindings[ff.Indices[2]] = vertLinkPerPoly[polyindex + 3];
                            //Bind materials
                            if (mesh.Header.Flags.HasFlag(BrgMeshFlag.MATERIAL))
                            {
                                ff.MaterialIndex = (short)mat.Id;
                            }
                            mesh.Faces.Add(ff);
                        }
                        polyindex += count * 2; //Including face normal bindings
                    }
                }
                else
                {
                    break;
                }

                //Locate the vertex normals
                Grendgine_Collada_Float_Array normalsArray = FindSourceByID(geo.Mesh, polyNormalsSourceID).Float_Array;
                if (normalsArray.Count != vertsArray.Count)
                {
                    System.Windows.Forms.MessageBox.Show("The mesh hash only face normals instead of vertex normals. Be sure to export only smooth shaded models.", "Model Import Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);
                }
                List <Vector3D> unsortedNormals = FloatToVectorArray(normalsArray);
                mesh.Normals = new List <Vector3D>(mesh.Header.NumVertices);
                for (int i = 0; i < mesh.Header.NumVertices; i++)
                {
                    mesh.Normals.Add(unsortedNormals[vertNormalBindings[i]]);
                }

                mesh.VertexMaterials = new List <short>(mesh.Header.NumVertices);
                for (int i = 0; i < mesh.Header.NumVertices; i++)
                {
                    mesh.VertexMaterials.Add((short)mat.Id);
                }
            }

            model.Header.NumMeshes = model.Meshes.Count();
        }
Ejemplo n.º 10
0
        private void ExportAttachpoints(string attachDummy, BrgMesh mesh, float time)
        {
            time += Maxscript.QueryFloat("animationRange.start.ticks / 4800.0");
            //System.Windows.Forms.MessageBox.Show("4");
            int numAttachpoints = Maxscript.QueryInteger("{0}.count", attachDummy);

            //System.Windows.Forms.MessageBox.Show("5 " + numAttachpoints);
            if (mesh.Header.Flags.HasFlag(BrgMeshFlag.ATTACHPOINTS))
            {
                mesh.Attachpoints = new List <BrgAttachpoint>();
                for (int i = 0; i < numAttachpoints; i++)
                {
                    string aName = Maxscript.QueryString("{0}[{1}].name", attachDummy, i + 1);
                    int    nameId;
                    if (!BrgAttachpoint.TryGetIdByName(aName.Substring(6), out nameId))
                    {
                        continue;
                    }
                    BrgAttachpoint att = new BrgAttachpoint();
                    //System.Windows.Forms.MessageBox.Show(aName);
                    //System.Windows.Forms.MessageBox.Show("5.1");
                    //System.Windows.Forms.MessageBox.Show(mesh.Attachpoints.Count + " " + i);
                    att.NameId = nameId;
                    Maxscript.Command("{0}[{1}].name = \"{2}\"", attachDummy, i + 1, att.GetMaxName());
                    //System.Windows.Forms.MessageBox.Show("5.2");
                    Maxscript.SetVarAtTime(time, "{0}Transform", "{0}[{1}].rotation as matrix3", attachDummy, i + 1);
                    Maxscript.SetVarAtTime(time, "{0}Position", "{0}[{1}].position", attachDummy, i + 1);
                    Maxscript.SetVarAtTime(time, "{0}Scale", "{0}[{1}].scale * {0}[{1}].boxsize", attachDummy, i + 1);
                    //System.Windows.Forms.MessageBox.Show("5.3");
                    Vector3 scale = new Vector3(Maxscript.QueryFloat("{0}Scale.X", attachDummy), Maxscript.QueryFloat("{0}Scale.Y", attachDummy), Maxscript.QueryFloat("{0}Scale.Z", attachDummy));
                    Vector3 bBox  = scale / 2;
                    //System.Windows.Forms.MessageBox.Show("5.4");

                    att.XVector.X = -Maxscript.QueryFloat("{0}Transform[1].z", attachDummy);
                    att.XVector.Y = Maxscript.QueryFloat("{0}Transform[3].z", attachDummy);
                    att.XVector.Z = -Maxscript.QueryFloat("{0}Transform[2].z", attachDummy);

                    att.YVector.X = -Maxscript.QueryFloat("{0}Transform[1].y", attachDummy);
                    att.YVector.Y = Maxscript.QueryFloat("{0}Transform[3].y", attachDummy);
                    att.YVector.Z = -Maxscript.QueryFloat("{0}Transform[2].y", attachDummy);

                    att.ZVector.X = -Maxscript.QueryFloat("{0}Transform[1].x", attachDummy);
                    att.ZVector.Y = Maxscript.QueryFloat("{0}Transform[3].x", attachDummy);
                    att.ZVector.Z = -Maxscript.QueryFloat("{0}Transform[2].x", attachDummy);

                    att.Position.X = -Maxscript.QueryFloat("{0}Position.x", attachDummy);
                    att.Position.Z = -Maxscript.QueryFloat("{0}Position.y", attachDummy);
                    att.Position.Y = Maxscript.QueryFloat("{0}Position.z", attachDummy);
                    //System.Windows.Forms.MessageBox.Show("5.5");

                    att.BoundingBoxMin.X = -bBox.X;
                    att.BoundingBoxMin.Z = -bBox.Y;
                    att.BoundingBoxMin.Y = -bBox.Z;
                    att.BoundingBoxMax.X = bBox.X;
                    att.BoundingBoxMax.Z = bBox.Y;
                    att.BoundingBoxMax.Y = bBox.Z;

                    mesh.Attachpoints.Add(att);
                }
                //System.Windows.Forms.MessageBox.Show("# Atpts: " + Attachpoint.Count);
            }
        }
Ejemplo n.º 11
0
        private void ExportBrgMesh(string mainObject, BrgMesh mesh, float time, Dictionary <int, int> matIdMapping)
        {
            time += Maxscript.QueryFloat("animationRange.start.ticks / 4800.0");

            string mainMesh       = "mainMesh";
            string mainObjectName = Maxscript.QueryString("{0}.name", mainObject);

            // Figure out the proper data to import
            if (!mesh.Header.Flags.HasFlag(BrgMeshFlag.SECONDARYMESH))
            {
                Maxscript.Command("{0} = ExportPreservedTexCoordData (GetMeshSnapshotAtTime {1} {2})", mainMesh, mainObject, time);
            }
            else
            {
                Maxscript.Command("{0} = GetMeshSnapshotAtTime {1} {2}", mainMesh, mainObject, time);
            }
            Maxscript.Command("ExportBrgVertNormals {0}", time);

            Maxscript.SetVarAtTime(time, "meshCenter", "{0}.center", mainObject);
            mesh.Header.CenterPosition = new Vector3
                                         (
                -Maxscript.QueryFloat("meshCenter.x"),
                Maxscript.QueryFloat("meshCenter.z"),
                -Maxscript.QueryFloat("meshCenter.y")
                                         );

            Maxscript.Command("grnd = getNodeByName \"Dummy_hotspot\"");
            if (!Maxscript.QueryBoolean("grnd == undefined"))
            {
                mesh.Header.HotspotPosition = new Vector3
                                              (
                    -Maxscript.QueryFloat("grnd.position.x"),
                    Maxscript.QueryFloat("grnd.position.z"),
                    -Maxscript.QueryFloat("grnd.position.y")
                                              );
            }

            Maxscript.SetVarAtTime(time, "{0}BBMax", "{0}.max", mainObject);
            Maxscript.SetVarAtTime(time, "{0}BBMin", "{0}.min", mainObject);
            Vector3 bBoxMax = new Vector3(Maxscript.QueryFloat("{0}BBMax.X", mainObject), Maxscript.QueryFloat("{0}BBMax.Y", mainObject), Maxscript.QueryFloat("{0}BBMax.Z", mainObject));
            Vector3 bBoxMin = new Vector3(Maxscript.QueryFloat("{0}BBMin.X", mainObject), Maxscript.QueryFloat("{0}BBMin.Y", mainObject), Maxscript.QueryFloat("{0}BBMin.Z", mainObject));
            Vector3 bBox    = (bBoxMax - bBoxMin) / 2;

            mesh.Header.MinimumExtent = new Vector3(-bBox.X, -bBox.Z, -bBox.Y);
            mesh.Header.MaximumExtent = new Vector3(bBox.X, bBox.Z, bBox.Y);

            int numVertices     = Maxscript.QueryInteger("brgVertIndices.count");
            int numFaces        = Maxscript.QueryInteger("brgFaceArray.count");
            int currNumVertices = mesh.Vertices.Count;

            //System.Windows.Forms.MessageBox.Show("1 " + numVertices);
            for (int i = 0; i < numVertices; i++)
            {
                //System.Windows.Forms.MessageBox.Show("1.1");
                try
                {
                    Maxscript.Command("vertex = getVert {0} brgVertIndices[{1}]", mainMesh, i + 1);
                    //System.Windows.Forms.MessageBox.Show("1.4");
                    mesh.Vertices.Add(new Vector3(-Maxscript.QueryFloat("vertex.x"), Maxscript.QueryFloat("vertex.z"), -Maxscript.QueryFloat("vertex.y")));

                    //System.Windows.Forms.MessageBox.Show("1.5");
                    mesh.Normals.Add(new Vector3(
                                         -Maxscript.QueryFloat("{0}[{1}].x", "averagedNormals", i + 1),
                                         Maxscript.QueryFloat("{0}[{1}].z", "averagedNormals", i + 1),
                                         -Maxscript.QueryFloat("{0}[{1}].y", "averagedNormals", i + 1)));
                    //System.Windows.Forms.MessageBox.Show("1.7");
                }
                catch (Exception ex)
                {
                    throw new Exception("In mesh " + mainObjectName + " error exporting verts/normals index " + (i + 1) + ".", ex);
                }
            }

            //System.Windows.Forms.MessageBox.Show("2");
            if (!mesh.Header.Flags.HasFlag(BrgMeshFlag.SECONDARYMESH) || mesh.Header.Flags.HasFlag(BrgMeshFlag.ANIMTEXCOORDS))
            {
                if (mesh.Header.Flags.HasFlag(BrgMeshFlag.TEXCOORDSA))
                {
                    for (int i = 0; i < numVertices; i++)
                    {
                        Maxscript.Command("tVert = getTVert {0} brgVertTVIndices[{1}]", mainMesh, i + 1);
                        mesh.TextureCoordinates.Add(new Vector3(Maxscript.QueryFloat("tVert.x"), Maxscript.QueryFloat("tVert.y"), 0f));
                    }
                }
            }

            //System.Windows.Forms.MessageBox.Show("3");
            if (!mesh.Header.Flags.HasFlag(BrgMeshFlag.SECONDARYMESH))
            {
                if (mesh.Header.Flags.HasFlag(BrgMeshFlag.MATERIAL))
                {
                    mesh.VertexMaterials.AddRange(new Int16[numVertices]);
                }
                for (int i = 0; i < numFaces; ++i)
                {
                    Face f = new Face();
                    mesh.Faces.Add(f);

                    if (mesh.Header.Flags.HasFlag(BrgMeshFlag.MATERIAL))
                    {
                        int faceMatId = Maxscript.QueryInteger("getFaceMatId {0} {1}", mainMesh, i + 1);
                        if (matIdMapping.ContainsKey(faceMatId))
                        {
                            f.MaterialIndex = (Int16)matIdMapping[faceMatId];
                        }
                        else
                        {
                            throw new Exception("In mesh " + mainObjectName + " face index " + (i + 1) + " has an invalid material id " + faceMatId + ".");
                        }
                    }

                    //System.Windows.Forms.MessageBox.Show("3.1");
                    Maxscript.Command("face = brgFaceArray[{0}]", i + 1);
                    f.Indices.Add((Int16)(Maxscript.QueryInteger("face.x") - 1 + currNumVertices));
                    f.Indices.Add((Int16)(Maxscript.QueryInteger("face.z") - 1 + currNumVertices));
                    f.Indices.Add((Int16)(Maxscript.QueryInteger("face.y") - 1 + currNumVertices));

                    //System.Windows.Forms.MessageBox.Show("3.2");
                    if (mesh.Header.Flags.HasFlag(BrgMeshFlag.MATERIAL))
                    {
                        mesh.VertexMaterials[f.Indices[0]] = f.MaterialIndex;
                        mesh.VertexMaterials[f.Indices[1]] = f.MaterialIndex;
                        mesh.VertexMaterials[f.Indices[2]] = f.MaterialIndex;
                    }
                }
            }

            Maxscript.Command("delete {0}", mainMesh);
        }
Ejemplo n.º 12
0
        public void Export()
        {
            BrgFile brg = this.File;

            Maxscript.Command("exportStartTime = timeStamp()");
            //Maxscript.Command("print heapSize");
            BrgMeshFlag              flags             = brg.Meshes[0].Header.Flags;
            BrgMeshFormat            format            = brg.Meshes[0].Header.Format;
            BrgMeshAnimType          animationType     = brg.Meshes[0].Header.AnimationType;
            BrgMeshInterpolationType interpolationType = brg.Meshes[0].Header.InterpolationType;

            Maxscript.Command("ExportBrgData()");
            int totalNumVerts = Maxscript.QueryInteger("brgtotalNumVerts");
            int totalNumFaces = Maxscript.QueryInteger("brgtotalNumFaces");
            int meshCount     = Maxscript.QueryInteger("brgMeshes.count");

            if (meshCount == 0)
            {
                throw new Exception("No Editable_Mesh objects detected!");
            }
            if (Maxscript.QueryBoolean("keys.Count == 0"))
            {
                throw new Exception("Could not acquire animation keys!");
            }

            brg.Header.NumMeshes = Maxscript.QueryInteger("keys.Count");
            brg.Animation        = new Animation();
            for (int i = 1; i <= brg.Header.NumMeshes; ++i)
            {
                brg.Animation.MeshKeys.Add(Maxscript.QueryFloat("keys[{0}]", i));
            }
            if (brg.Header.NumMeshes == 1)
            {
                brg.Animation.Duration = 0;
            }
            else
            {
                brg.Animation.Duration = Maxscript.QueryFloat("(animationRange.end.ticks - animationRange.start.ticks) / 4800.0");
            }
            brg.Animation.TimeStep = brg.Animation.Duration / (float)brg.Header.NumMeshes;

            string mainObject = "mainObject";

            brg.Materials = new List <BrgMaterial>();
            brg.Meshes    = new List <BrgMesh>(brg.Header.NumMeshes);
            for (int m = 0; m < meshCount; ++m)
            {
                Maxscript.Command("{0} = brgMeshes[{1}]", mainObject, m + 1);

                // Materials
                Dictionary <int, int> matIdMapping = new Dictionary <int, int>();
                if (Maxscript.QueryBoolean("classof {0}.material == Multimaterial", mainObject))
                {
                    brg.Header.NumMaterials = Maxscript.QueryInteger("{0}.material.materialList.count", mainObject);
                    for (int i = 0; i < brg.Header.NumMaterials; i++)
                    {
                        BrgMaterial mat = new BrgMaterial(brg);
                        mat.Id = brg.Materials.Count + 1;
                        Maxscript.Command("mat = {0}.material.materialList[{1}]", mainObject, i + 1);
                        this.ExportBrgMaterial(mainObject, mat);

                        int matListIndex = brg.Materials.IndexOf(mat);
                        int actualMatId  = Maxscript.QueryInteger("{0}.material.materialIdList[{1}]", mainObject, i + 1);
                        if (matListIndex >= 0)
                        {
                            if (!matIdMapping.ContainsKey(actualMatId))
                            {
                                matIdMapping.Add(actualMatId, brg.Materials[matListIndex].Id);
                            }
                        }
                        else
                        {
                            brg.Materials.Add(mat);
                            if (matIdMapping.ContainsKey(actualMatId))
                            {
                                matIdMapping[actualMatId] = mat.Id;
                            }
                            else
                            {
                                matIdMapping.Add(actualMatId, mat.Id);
                            }
                        }
                    }
                }
                else if (Maxscript.QueryBoolean("classof {0}.material == Standardmaterial", mainObject))
                {
                    BrgMaterial mat = new BrgMaterial(brg);
                    mat.Id = brg.Materials.Count + 1;
                    Maxscript.Command("mat = {0}.material", mainObject);
                    this.ExportBrgMaterial(mainObject, mat);

                    int matListIndex = brg.Materials.IndexOf(mat);
                    if (matListIndex >= 0)
                    {
                        matIdMapping.Add(1, brg.Materials[matListIndex].Id);
                    }
                    else
                    {
                        brg.Materials.Add(mat);
                        matIdMapping.Add(1, mat.Id);
                    }
                }
                else
                {
                    if (flags.HasFlag(BrgMeshFlag.MATERIAL))
                    {
                        throw new Exception("Not all meshes have a material applied! " + Maxscript.QueryString("{0}.name", mainObject));
                    }
                }

                // Mesh Animations
                for (int i = 0; i < brg.Header.NumMeshes; i++)
                {
                    if (i > 0)
                    {
                        if (m == 0)
                        {
                            BrgMesh mesh = new BrgMesh(brg);
                            mesh.Vertices           = new List <Vector3>(totalNumVerts);
                            mesh.Normals            = new List <Vector3>(totalNumVerts);
                            mesh.TextureCoordinates = new List <Vector3>(totalNumVerts);
                            mesh.Faces = new List <Face>(totalNumFaces);
                            brg.Meshes[0].MeshAnimations.Add(mesh);
                        }
                        brg.UpdateMeshSettings(i, flags, format, animationType, interpolationType);
                        this.ExportBrgMesh(mainObject, (BrgMesh)brg.Meshes[0].MeshAnimations[i - 1], brg.Animation.MeshKeys[i], matIdMapping);
                    }
                    else
                    {
                        if (m == 0)
                        {
                            BrgMesh mesh = new BrgMesh(brg);
                            mesh.Vertices           = new List <Vector3>(totalNumVerts);
                            mesh.Normals            = new List <Vector3>(totalNumVerts);
                            mesh.TextureCoordinates = new List <Vector3>(totalNumVerts);
                            mesh.Faces = new List <Face>(totalNumFaces);
                            brg.Meshes.Add(mesh);
                        }
                        brg.UpdateMeshSettings(i, flags, format, animationType, interpolationType);
                        this.ExportBrgMesh(mainObject, brg.Meshes[i], brg.Animation.MeshKeys[i], matIdMapping);
                    }
                }
            }

            // Export Attachpoints, and Update some Mesh data
            HashSet <int> usedFaceMaterials = new HashSet <int>();
            string        attachDummy       = Maxscript.NewArray("attachDummy");

            Maxscript.Command("{0} = for helpObj in ($helpers/Dummy_*) where classof helpObj == Dummy collect helpObj", attachDummy);//"$helpers/Dummy_* as array");
            for (int i = 0; i < brg.Header.NumMeshes; i++)
            {
                BrgMesh mesh;
                if (i > 0)
                {
                    mesh = (BrgMesh)brg.Meshes[0].MeshAnimations[i - 1];
                }
                else
                {
                    mesh = brg.Meshes[i];
                }

                this.ExportAttachpoints(attachDummy, mesh, brg.Animation.MeshKeys[i]);
                HashSet <int> diffFaceMats = new HashSet <int>();
                if (!mesh.Header.Flags.HasFlag(BrgMeshFlag.SECONDARYMESH) &&
                    mesh.Header.Flags.HasFlag(BrgMeshFlag.MATERIAL))
                {
                    for (int j = 0; j < mesh.Faces.Count; ++j)
                    {
                        diffFaceMats.Add(mesh.Faces[j].MaterialIndex);
                    }

                    if (diffFaceMats.Count > 0)
                    {
                        mesh.ExtendedHeader.NumMaterials       = (byte)(diffFaceMats.Count - 1);
                        mesh.ExtendedHeader.NumUniqueMaterials = diffFaceMats.Count;
                    }
                }
                usedFaceMaterials.UnionWith(diffFaceMats);
                mesh.ExtendedHeader.AnimationLength = this.File.Animation.Duration;
            }
            List <BrgMaterial> usedMats = new List <BrgMaterial>(brg.Materials.Count);

            for (int i = 0; i < brg.Materials.Count; ++i)
            {
                if (usedFaceMaterials.Contains(brg.Materials[i].Id))
                {
                    usedMats.Add(brg.Materials[i]);
                }
            }
            brg.Materials           = usedMats;
            brg.Header.NumMaterials = brg.Materials.Count;

            //Maxscript.Command("print heapSize");
            Maxscript.Command("exportEndTime = timeStamp()");
            Maxscript.Format("Export took % seconds\n", "((exportEndTime - exportStartTime) / 1000.0)");
        }
Ejemplo n.º 13
0
        private void ImportBrgMesh(string mainObject, BrgMesh mesh, float time)
        {
            string vertArray = "";
            string normArray = "";
            string texVerts  = "";
            string faceMats  = "";
            string faceArray = "";

            if (!mesh.Header.Flags.HasFlag(BrgMeshFlag.SECONDARYMESH))
            {
                vertArray = Maxscript.NewArray("vertArray");
                normArray = Maxscript.NewArray("normArray");
                texVerts  = Maxscript.NewArray("texVerts");

                faceMats  = Maxscript.NewArray("faceMats");
                faceArray = Maxscript.NewArray("faceArray");
            }

            Maxscript.CommentTitle("Load Vertices/Normals/UVWs");
            Maxscript.Command("uvwSetVertPosFunc = {0}.Unwrap_UVW.SetVertexPosition", mainObject);
            for (int i = 0; i < mesh.Vertices.Count; i++)
            {
                if (mesh.Header.Flags.HasFlag(BrgMeshFlag.SECONDARYMESH))
                {
                    Maxscript.AnimateAtTime(time, "meshSetVertFunc {0} {1} {2}", mainObject, i + 1,
                                            Maxscript.Point3Literal(-mesh.Vertices[i].X, -mesh.Vertices[i].Z, mesh.Vertices[i].Y));

                    if (mesh.Header.Flags.HasFlag(BrgMeshFlag.ANIMTEXCOORDS) &&
                        mesh.Header.Flags.HasFlag(BrgMeshFlag.TEXCOORDSA))
                    {
                        Maxscript.Animate("uvwSetVertPosFunc {0}s {1} {2}", time, i + 1,
                                          Maxscript.Point3Literal(mesh.TextureCoordinates[i].X, mesh.TextureCoordinates[i].Y, 0));
                    }

                    if (mesh.Header.Flags.HasFlag(BrgMeshFlag.ANIMVERTCOLORALPHA))
                    {
                        if (mesh.Header.Flags.HasFlag(BrgMeshFlag.COLORALPHACHANNEL))
                        {
                            Maxscript.AnimateAtTime(time, "meshop.setVertAlpha {0} -2 {1} {2}",
                                                    mainObject, i + 1, mesh.Colors[i].A);
                        }
                        else if (mesh.Header.Flags.HasFlag(BrgMeshFlag.COLORCHANNEL))
                        {
                            Maxscript.AnimateAtTime(time, "meshop.setVertColor {0} 0 {1} (color {2} {3} {4})", mainObject, i + 1,
                                                    mesh.Colors[i].R, mesh.Colors[i].G, mesh.Colors[i].B);
                        }
                    }
                }
                else
                {
                    Maxscript.Append(vertArray, Maxscript.Point3Literal(-mesh.Vertices[i].X, -mesh.Vertices[i].Z, mesh.Vertices[i].Y));

                    if (mesh.Header.Flags.HasFlag(BrgMeshFlag.TEXCOORDSA))
                    {
                        Maxscript.Append(texVerts, Maxscript.Point3Literal(mesh.TextureCoordinates[i].X, mesh.TextureCoordinates[i].Y, 0));
                    }

                    if (mesh.Header.Flags.HasFlag(BrgMeshFlag.COLORALPHACHANNEL))
                    {
                        //Maxscript.Command("meshop.supportVAlphas {0}", mainObject);
                        Maxscript.Command("meshop.setVertAlpha {0} -2 {1} {2}",
                                          mainObject, i + 1, mesh.Colors[i].A);
                    }
                    else if (mesh.Header.Flags.HasFlag(BrgMeshFlag.COLORCHANNEL))
                    {
                        Maxscript.Command("meshop.setVertColor {0} 0 {1} (color {2} {3} {4})", mainObject, i + 1,
                                          mesh.Colors[i].R, mesh.Colors[i].G, mesh.Colors[i].B);
                    }
                }
            }

            if (!mesh.Header.Flags.HasFlag(BrgMeshFlag.SECONDARYMESH))
            {
                if (mesh.Header.Flags.HasFlag(BrgMeshFlag.MATERIAL))
                {
                    Maxscript.CommentTitle("Load Face Materials");
                    foreach (var fMat in mesh.Faces)
                    {
                        Maxscript.Append(faceMats, fMat.MaterialIndex);
                    }
                }

                Maxscript.CommentTitle("Load Faces");
                foreach (var face in mesh.Faces)
                {
                    Maxscript.Append(faceArray, Maxscript.Point3Literal(face.Indices[0] + 1, face.Indices[2] + 1, face.Indices[1] + 1));
                }

                int mObjNum = 0;
                while (Maxscript.QueryInteger("($objects/{0}* as array).count", mainObject + mObjNum) > 0)
                {
                    ++mObjNum;
                }
                Maxscript.Command("{0} = {1}", mainObject, Maxscript.NewMeshLiteral(mainObject + mObjNum, vertArray, faceArray, faceMats, texVerts));
                //Maxscript.Command("{0} = getNodeByName \"{0}\"", mainObject);

                Maxscript.Command("dummy name:\"Dummy_hotspot\" pos:{0} boxsize:[10,10,0]", Maxscript.Point3Literal(-mesh.Header.HotspotPosition.X, -mesh.Header.HotspotPosition.Z, mesh.Header.HotspotPosition.Y));

                Maxscript.CommentTitle("TVert Hack"); // Needed <= 3ds Max 2014; idk about 2015+
                Maxscript.Command("buildTVFaces {0}", mainObject);
                for (int i = 1; i <= mesh.Faces.Count; i++)
                {
                    Maxscript.Command("setTVFace {0} {1} {2}[{1}]", mainObject, i, faceArray);
                }

                Maxscript.CommentTitle("Load Normals for first Frame");
                Maxscript.Command("max modify mode");
                Maxscript.Command("select {0}", mainObject);
                Maxscript.Command("addModifier {0} (Edit_Normals()) ui:off", mainObject);
                Maxscript.Command("modPanel.setCurrentObject {0}.modifiers[#edit_normals]", mainObject);

                Maxscript.Command("{0}.modifiers[#edit_normals].Break selection:#{{1..{1}}}", mainObject, mesh.Normals.Count);
                Maxscript.Command("meshSetNormalIdFunc = {0}.modifiers[#edit_normals].SetNormalID", mainObject);
                for (int i = 0; i < mesh.Faces.Count; ++i)
                {
                    Maxscript.Command("meshSetNormalIdFunc {0} {1} {2}",
                                      i + 1, 1, mesh.Faces[i].Indices[0] + 1);
                    Maxscript.Command("meshSetNormalIdFunc {0} {1} {2}",
                                      i + 1, 2, mesh.Faces[i].Indices[2] + 1);
                    Maxscript.Command("meshSetNormalIdFunc {0} {1} {2}",
                                      i + 1, 3, mesh.Faces[i].Indices[1] + 1);
                }
                Maxscript.Command("{0}.modifiers[#edit_normals].MakeExplicit selection:#{{1..{1}}}", mainObject, mesh.Normals.Count);
                Maxscript.Command("meshSetNormalFunc = {0}.modifiers[#edit_normals].SetNormal", mainObject);
                for (int i = 0; i < mesh.Normals.Count; i++)
                {
                    Maxscript.Command("meshSetNormalFunc {0} {1}", i + 1,
                                      Maxscript.Point3Literal(-mesh.Normals[i].X, -mesh.Normals[i].Z, mesh.Normals[i].Y));
                }
                Maxscript.Command("collapseStack {0}", mainObject);

                if (mesh.Header.Flags.HasFlag(BrgMeshFlag.ANIMTEXCOORDS))
                {
                    Maxscript.Command("select {0}", mainObject);
                    Maxscript.Command("addModifier {0} (Unwrap_UVW()) ui:off", mainObject);

                    Maxscript.Command("select {0}.verts", mainObject);
                    Maxscript.Animate("{0}.Unwrap_UVW.moveSelected [0,0,0]", mainObject);
                }
            }

            Maxscript.CommentTitle("Load Attachpoints");
            string attachDummyArray = "attachDummyArray";

            if (!mesh.Header.Flags.HasFlag(BrgMeshFlag.SECONDARYMESH))
            {
                Maxscript.NewArray(attachDummyArray);
            }
            for (int i = 0; i < mesh.Attachpoints.Count; ++i)
            {
                BrgAttachpoint att = mesh.Attachpoints[i];
                if (mesh.Header.Flags.HasFlag(BrgMeshFlag.SECONDARYMESH))
                {
                    Maxscript.Command("attachpoint = {0}[{1}]", attachDummyArray, i + 1);
                    Maxscript.AnimateAtTime(time, "attachpoint.rotation = {0}", att.GetMaxTransform());
                    Maxscript.AnimateAtTime(time, "attachpoint.position = {0}", att.GetMaxPosition());
                    if (this.uniformAttachpointScale)
                    {
                        Maxscript.AnimateAtTime(time, "attachpoint.scale = [1,1,1]");
                    }
                    else
                    {
                        Maxscript.AnimateAtTime(time, "attachpoint.scale = {0}", att.GetMaxScale());
                    }
                }
                else
                {
                    string attachDummy;
                    if (this.uniformAttachpointScale)
                    {
                        attachDummy = Maxscript.NewDummy("attachDummy", att.GetMaxName(), att.GetMaxTransform(), att.GetMaxPosition(), "[0.25,0.25,0.25]", "[1,1,1]");
                    }
                    else
                    {
                        attachDummy = Maxscript.NewDummy("attachDummy", att.GetMaxName(), att.GetMaxTransform(), att.GetMaxPosition(), att.GetMaxBoxSize(), att.GetMaxScale());
                    }
                    Maxscript.Command("append {0} {1}", attachDummyArray, attachDummy);
                }
            }
        }
Ejemplo n.º 14
0
        private void FromBrgMesh(BrgMesh brgMesh)
        {
            Vector3 max = new Vector3(float.MinValue);
            Vector3 min = new Vector3(float.MaxValue);

            using (FileStream fs = File.Open("posBuffer.bin", FileMode.Create, FileAccess.Write, FileShare.Read))
                using (BinaryWriter writer = new BinaryWriter(fs))
                {
                    foreach (Vector3 vec in brgMesh.Vertices)
                    {
                        max.X = Math.Max(max.X, vec.X);
                        max.Y = Math.Max(max.Y, vec.Y);
                        max.Z = Math.Max(max.Z, vec.Z);

                        min.X = Math.Min(min.X, vec.X);
                        min.Y = Math.Min(min.Y, vec.Y);
                        min.Z = Math.Min(min.Z, vec.Z);

                        writer.Write(vec.X);
                        writer.Write(vec.Y);
                        writer.Write(vec.Z);
                    }
                }

            glTFLoader.Schema.Buffer posBuffer = new glTFLoader.Schema.Buffer();
            posBuffer.ByteLength = brgMesh.Vertices.Count * 12;
            posBuffer.Uri        = "posBuffer.bin";

            BufferView posBufferView = new BufferView();

            posBufferView.Buffer     = 0;
            posBufferView.ByteLength = posBuffer.ByteLength;
            posBufferView.ByteOffset = 0;
            posBufferView.ByteStride = 12;
            posBufferView.Name       = "posBufferView";
            posBufferView.Target     = BufferView.TargetEnum.ARRAY_BUFFER;

            Accessor posAccessor = new Accessor();

            posAccessor.BufferView    = 0;
            posAccessor.ByteOffset    = 0;
            posAccessor.ComponentType = Accessor.ComponentTypeEnum.FLOAT;
            posAccessor.Count         = brgMesh.Vertices.Count;
            posAccessor.Max           = new[] { max.X, max.Y, max.Z };
            posAccessor.Min           = new[] { min.X, min.Y, min.Z };
            posAccessor.Name          = "posBufferViewAccessor";
            posAccessor.Type          = Accessor.TypeEnum.VEC3;

            short faceMin = short.MaxValue;
            short faceMax = short.MinValue;

            using (FileStream fs = File.Open("indexBuffer.bin", FileMode.Create, FileAccess.Write, FileShare.Read))
                using (BinaryWriter writer = new BinaryWriter(fs))
                {
                    foreach (var face in brgMesh.Faces)
                    {
                        faceMin = Math.Min(faceMin, face.Indices[0]);
                        faceMin = Math.Min(faceMin, face.Indices[1]);
                        faceMin = Math.Min(faceMin, face.Indices[2]);

                        faceMax = Math.Max(faceMax, face.Indices[0]);
                        faceMax = Math.Max(faceMax, face.Indices[1]);
                        faceMax = Math.Max(faceMax, face.Indices[2]);

                        writer.Write(face.Indices[0]);
                        writer.Write(face.Indices[1]);
                        writer.Write(face.Indices[2]);
                    }
                }

            glTFLoader.Schema.Buffer indexBuffer = new glTFLoader.Schema.Buffer();
            indexBuffer.ByteLength = brgMesh.Faces.Count * 6;
            indexBuffer.Uri        = "indexBuffer.bin";

            BufferView indexBufferView = new BufferView();

            indexBufferView.Buffer     = 1;
            indexBufferView.ByteLength = indexBuffer.ByteLength;
            indexBufferView.ByteOffset = 0;
            indexBufferView.Name       = "indexBufferView";
            indexBufferView.Target     = BufferView.TargetEnum.ELEMENT_ARRAY_BUFFER;

            Accessor indexAccessor = new Accessor();

            indexAccessor.BufferView    = 1;
            indexAccessor.ByteOffset    = 0;
            indexAccessor.ComponentType = Accessor.ComponentTypeEnum.UNSIGNED_SHORT;
            indexAccessor.Count         = brgMesh.Faces.Count * 3;
            indexAccessor.Max           = new[] { (float)faceMax };
            indexAccessor.Min           = new[] { (float)faceMin };
            indexAccessor.Name          = "indexBufferViewAccessor";
            indexAccessor.Type          = Accessor.TypeEnum.SCALAR;

            gltf.Buffers     = new[] { posBuffer, indexBuffer };
            gltf.BufferViews = new[] { posBufferView, indexBufferView };
            gltf.Accessors   = new[] { posAccessor, indexAccessor };

            MeshPrimitive meshPrimitive = new MeshPrimitive();

            meshPrimitive.Attributes = new Dictionary <string, int>();
            meshPrimitive.Attributes.Add("POSITION", 0);
            meshPrimitive.Indices = 1;
            meshPrimitive.Mode    = MeshPrimitive.ModeEnum.TRIANGLES;

            var mesh = new glTFLoader.Schema.Mesh();

            mesh.Name       = "mesh";
            mesh.Primitives = new[] { meshPrimitive };

            gltf.Meshes = new[] { mesh };

            Node node = new Node();

            node.Mesh = 0;
            node.Name = "node";

            gltf.Nodes = new[] { node };
        }