Beispiel #1
0
        public void ExportToFile(string resourceName, string fileName, VModel model)
        {
            var exportedModel = ModelRoot.CreateModel();

            exportedModel.Asset.Generator = GENERATOR;
            var scene             = exportedModel.UseScene(Path.GetFileName(resourceName));
            var embeddedMeshIndex = 0;

            foreach (var mesh in model.GetEmbeddedMeshes())
            {
                var name         = $"Embedded Mesh {++embeddedMeshIndex}";
                var exportedMesh = CreateGltfMesh(name, mesh, exportedModel);
                scene.CreateNode(name)
                .WithMesh(exportedMesh);
            }

            foreach (var meshReference in model.GetReferencedMeshNames())
            {
                var meshResource = GuiContext.LoadFileByAnyMeansNecessary(meshReference + "_c");

                if (meshResource == null)
                {
                    continue;
                }

                var nodeName     = Path.GetFileNameWithoutExtension(meshReference);
                var mesh         = new VMesh(meshResource);
                var exportedMesh = CreateGltfMesh(nodeName, mesh, exportedModel);

                scene.CreateNode(nodeName)
                .WithMesh(exportedMesh);
            }

            exportedModel.Save(fileName);
        }
Beispiel #2
0
 public virtual void Render(VMesh m)
 {
     foreach (VRenderLayer rl in Layers)
     {
         rl.Render(m, m.Viz);
     }
 }
Beispiel #3
0
            public void Init(EditableMesh m)
            {
                sm_Instance = this;

                m_EditMesh = m;
                m_RealMesh = m_EditMesh.mesh;

                //ETimeProf prof = new ETimeProf();
                m_DegRTriCont = new DegradeRTriCont();

                // map VV <-> RV
                m_VVertCont = new VVertCont();
                _InitVVertTable();

                //prof.Click("VMesh.Init.VVertTable:");

                // establish VEdge table
                m_VEdgeCont = new VEdgeCont();
                _InitVEdgeTable();
                //prof.Click("VMesh.Init.VEdgeTable:");

                // establish VQuad table
                m_VFaceCont = new VFaceCont();
                _InitVFaceTable();
                //prof.Click("VMesh.Init.VQuadTable:");
            }
        /// <summary>
        /// Export a Valve VMDL to GLTF.
        /// </summary>
        /// <param name="resourceName">The name of the resource being exported.</param>
        /// <param name="fileName">Target file name.</param>
        /// <param name="model">The model resource to export.</param>
        public void ExportToFile(string resourceName, string fileName, VModel model)
        {
            var exportedModel = ModelRoot.CreateModel();

            exportedModel.Asset.Generator = GENERATOR;
            var scene             = exportedModel.UseScene(Path.GetFileName(resourceName));
            var embeddedMeshIndex = 0;

            void AddMeshNode(string name, VMesh mesh)
            {
                var exportedMesh = CreateGltfMesh(name, mesh, exportedModel, true);

                // Add skeleton and skin
                var modelSkeleton = model.GetSkeleton();

                if (modelSkeleton.AnimationTextureSize > 0)
                {
                    var skeleton = scene.CreateNode(name);
                    var joints   = CreateGltfSkeleton(modelSkeleton, skeleton);

                    scene.CreateNode(name)
                    .WithSkinnedMesh(exportedMesh, Matrix4x4.Identity, joints);

                    // Rotate upright, scale inches to meters.
                    skeleton.WorldMatrix = TRANSFORMSOURCETOGLTF;
                }
                else
                {
                    var meshNode = scene.CreateNode(name)
                                   .WithMesh(exportedMesh);

                    // Rotate upright, scale inches to meters.
                    meshNode.WorldMatrix = TRANSFORMSOURCETOGLTF;
                }
            }

            // Add embedded meshes
            foreach (var mesh in model.GetEmbeddedMeshes())
            {
                var name = $"Embedded Mesh {++embeddedMeshIndex}";
                AddMeshNode(name, mesh);
            }

            // Add external meshes
            foreach (var meshReference in model.GetReferencedMeshNames())
            {
                var meshResource = GuiContext.LoadFileByAnyMeansNecessary(meshReference + "_c");
                if (meshResource == null)
                {
                    continue;
                }

                var nodeName = Path.GetFileNameWithoutExtension(meshReference);
                var mesh     = new VMesh(meshResource);

                AddMeshNode(nodeName, mesh);
            }

            exportedModel.Save(fileName);
        }
Beispiel #5
0
        // private method

        private void _PrepareEdgeIndices()
        {
            VMesh vmesh = VMesh.Instance;

            VVert[] allVVerts = vmesh.GetAllVVerts();
            VEdge[] allVEdges = vmesh.GetAllVActiveEdges();

            Dictionary <VVert, int> vert2idx = new Dictionary <VVert, int>();

            for (int i = 0; i < allVVerts.Length; ++i)
            {
                VVert v = allVVerts[i];
                vert2idx[v] = i;
            }

            m_EdgeIndices = new int[allVEdges.Length * 2];

            for (int i = 0; i < allVEdges.Length; i++)
            {
                VEdge e     = allVEdges[i];
                VVert v0    = e.GetVVert(0);
                VVert v1    = e.GetVVert(1);
                int   vidx0 = vert2idx[v0];
                int   vidx1 = vert2idx[v1];

                m_EdgeIndices[i * 2]     = vidx0;
                m_EdgeIndices[i * 2 + 1] = vidx1;
            }
        }
Beispiel #6
0
        public static void Cube(float s)
        {
            VMesh m = new VMesh(32, 8);



            VSceneEntity e = new VSceneEntity();

            e.AddMesh(m);
            e.Meshes[0].Final();
        }
Beispiel #7
0
 public override void Render(VMesh m, VVisualizer v)
 {
     // m.Mat.Bind();
     fx.Bind();
     v.SetMesh(m);
     v.Bind();
     v.Visualize();
     v.Release();
     fx.Release();
     //m.Mat.Release();
 }
Beispiel #8
0
 public override void Render(VMesh m, VVisualizer v)
 {
     m.Mat.Bind();
     Lighting.GraphLight3D.Active.ShadowFB.Cube.Bind(2);
     fx.Bind();
     v.SetMesh(m);
     v.Bind();
     v.Visualize();
     v.Release();
     fx.Release();
     Lighting.GraphLight3D.Active.ShadowFB.Cube.Release(2);
     m.Mat.Release();
 }
Beispiel #9
0
        /// <summary>
        /// update the markers, if not dirty, do nothing;
        ///
        /// will retrieve info from Mesh & Selection & other related external data-structures
        /// </summary>
        public void UpdateMarkers()
        {
            if (!Dirty)
            {
                return;
            }

            //Mesh m = m_EditMesh.mesh;
            //Transform meshTr = m_EditMesh.transform;
            //Vector3[] verts = MeshCache.Instance.vertices;

            VMesh vmesh = VMesh.Instance;

            // vert positions
            VVert[] allVVerts = vmesh.GetAllVVerts();
            int     vcnt      = allVVerts.Length;

            Vector3[] allVVertPos = new Vector3[vcnt];
            for (int i = 0; i < vcnt; ++i)
            {
                allVVertPos[i] = allVVerts[i].GetWorldPos();
            }

            // colors
            Color32[] colors = new Color32[vcnt];
            for (int i = 0; i < vcnt; ++i)
            {
                VVert oneVVert = allVVerts[i];
                if (m_Selection.IsSelectedVert(oneVVert.RepVert))
                {
                    colors[i] = SelectedVertColor;
                }
                else
                {
                    colors[i] = NonSelectedVertColor;
                }
            }

            // set to mesh(vert)
            m_VertMarker.SetVerts(allVVertPos); //indices are set altogether with vertices
            m_VertMarker.SetColors(colors);

            // set to mesh(edge)
            m_EdgeMarker.SetVerts(allVVertPos);
            m_EdgeMarker.SetColors(colors);
            m_EdgeMarker.SetIndices(m_EdgeIndices);

            Dirty = false;
        }
Beispiel #10
0
        public void ExportToFile(string resourceName, string fileName, VMesh mesh)
        {
            var exportedModel = ModelRoot.CreateModel();

            exportedModel.Asset.Generator = GENERATOR;
            var name  = Path.GetFileName(resourceName);
            var scene = exportedModel.UseScene(name);

            var exportedMesh = CreateGltfMesh(name, mesh, exportedModel);

            scene.CreateNode(name)
            .WithMesh(exportedMesh);

            exportedModel.Save(fileName);
        }
Beispiel #11
0
            /// <summary>
            /// get VFaces that containing this VEdge
            /// </summary>
            public void GetVFaces(List <VFace> vFaces)
            {
                vFaces.Clear();
                VMesh vmesh = VMesh.Instance;

                for (int i = 0; i < m_TriCont.Count; ++i)
                {
                    int   triIdx = m_TriCont[i];
                    VFace vf     = vmesh.GetVFaceFromRTri(triIdx);
                    if (!vFaces.Contains(vf))
                    {
                        vFaces.Add(vf);
                    }
                }
            }
Beispiel #12
0
            /// <summary>
            /// NOTE: when with 2 tris, the order is:
            /// tri0: 012, tri1: 123
            ///
            /// </summary>
            public void AddRTri(int rTriIdx)
            {
                //Dbg.Log("VFace{0}, AddRTri: {1}", m_Idx, rTriIdx);
                Dbg.Assert(m_rTriCnt < 2, "VFace.AddRTri: already have 2 rtris");
                m_rTriIdxs[m_rTriCnt] = rTriIdx;
                ++m_rTriCnt;

                VVert vv0, vv1, vv2;
                VMesh vmesh = VMesh.Instance;

                vmesh.GetVVertsFromRTri(rTriIdx, out vv0, out vv1, out vv2);

                if (m_rTriCnt == 1)
                {
                    m_VVertLst.Add(vv0);
                    m_VVertLst.Add(vv1);
                    m_VVertLst.Add(vv2);
                }
                else
                { //merge with another tri, must ensure order of verts
                    // set lst[0]
                    for (int i = 0; i < 3; ++i)
                    {
                        if (m_VVertLst[i] != vv0 && m_VVertLst[i] != vv1 && m_VVertLst[i] != vv2)
                        {
                            if (i != 0)
                            {
                                VVert tmp = m_VVertLst[0];
                                m_VVertLst[0] = m_VVertLst[i];
                                m_VVertLst[i] = tmp;
                            }
                            break;
                        }
                    }

                    //set lst[3]
                    VVert[] verts = new VVert[] { vv0, vv1, vv2 };
                    for (int i = 0; i < 3; ++i)
                    {
                        if (verts[i] != m_VVertLst[1] && verts[i] != m_VVertLst[2])
                        {
                            m_VVertLst.Add(verts[i]);
                            break;
                        }
                    }
                    Dbg.Assert(m_VVertLst.Count == 4, "VFace.AddTri: adding new tri, but no new vert added?!");
                }
            }
        /// <summary>
        /// Export a Valve VMESH to Gltf.
        /// </summary>
        /// <param name="resourceName">The name of the resource being exported.</param>
        /// <param name="fileName">Target file name.</param>
        /// <param name="mesh">The mesh resource to export.</param>
        public void ExportToFile(string resourceName, string fileName, VMesh mesh)
        {
            var exportedModel = ModelRoot.CreateModel();

            exportedModel.Asset.Generator = GENERATOR;
            var name  = Path.GetFileName(resourceName);
            var scene = exportedModel.UseScene(name);

            var exportedMesh = CreateGltfMesh(name, mesh, exportedModel, false);
            var meshNode     = scene.CreateNode(name)
                               .WithMesh(exportedMesh);

            // Swap Rotate upright, scale inches to meters.
            meshNode.WorldMatrix = TRANSFORMSOURCETOGLTF;

            exportedModel.Save(fileName);
        }
Beispiel #14
0
 public virtual void RenderDepth(VMesh m)
 {
     RLD.Render(m, m.Viz);
 }
Beispiel #15
0
 public void Fini()
 {
     sm_Instance = null;
 }
Beispiel #16
0
 public virtual void Bind(VMesh m)
 {
 }
Beispiel #17
0
 public override void SetMesh(VMesh m)
 {
     md = m;
 }
Beispiel #18
0
 public virtual void Release(VMesh m, VVisualizer v)
 {
 }
Beispiel #19
0
 public virtual void Render(VMesh m, VVisualizer v)
 {
 }
Beispiel #20
0
 public virtual void SetMesh(VMesh m)
 {
 }
Beispiel #21
0
        /// <summary>
        /// Loads the VMesh into our Objmesh
        /// </summary>
        /// <param name="objMesh">The objmesh to load into</param>
        /// <param name="mesh">The VMesh to load</param>
        private void LoadVMeshIntoMesh(ObjMesh objMesh, VMesh mesh)
        {
            var data = mesh.GetData();
            var vbib = mesh.VBIB;

            foreach (var sceneObject in data.GetArray("m_sceneObjects"))
            {
                foreach (var drawCall in sceneObject.GetArray("m_drawCalls"))
                {
                    var startingVertexCount = objMesh.Positions.Count;                 // Set this so we can offset the indicies for triangles correctly
                    var vertexBufferInfo    = drawCall.GetArray("m_vertexBuffers")[0]; // In what situation can we have more than 1 vertex buffer per draw call?
                    var vertexBufferIndex   = (int)vertexBufferInfo.GetIntegerProperty("m_hBuffer");
                    var vertexBuffer        = vbib.VertexBuffers[vertexBufferIndex];

                    var indexBufferInfo  = drawCall.GetSubCollection("m_indexBuffer");
                    var indexBufferIndex = (int)indexBufferInfo.GetIntegerProperty("m_hBuffer");
                    var indexBuffer      = vbib.IndexBuffers[indexBufferIndex];

                    // Set vertex attributes
                    foreach (var attribute in vertexBuffer.Attributes)
                    {
                        var buffer        = ReadAttributeBuffer(vertexBuffer, attribute);
                        var numComponents = buffer.Length / vertexBuffer.Count;


                        if (attribute.Name == "BLENDINDICES")
                        {
                            var byteBuffer    = buffer.Select(f => (byte)f).ToArray();
                            var rawBufferData = new byte[buffer.Length];
                            System.Buffer.BlockCopy(byteBuffer, 0, rawBufferData, 0, rawBufferData.Length);

                            var blendIndices = rawBufferData.ChunkBy(4);

                            objMesh.BlendIndices.AddRange(blendIndices);

                            continue;
                        }

                        if (attribute.Name == "BLENDWEIGHT")
                        {
                            var vectors = ToVector4Array(buffer);
                            objMesh.BlendWeights.AddRange(vectors);
                        }

                        if (attribute.Name == "POSITION")
                        {
                            var vectors = ToVector3Array(buffer);
                            objMesh.Positions.AddRange(vectors);
                        }

                        if (attribute.Name == "NORMAL")
                        {
                            if (VMesh.IsCompressedNormalTangent(drawCall))
                            {
                                var vectors = ToVector4Array(buffer);
                                var(normals, tangents) = DecompressNormalTangents(vectors);
                                objMesh.Normals.AddRange(normals);
                            }
                            else
                            {
                                var vectors = ToVector3Array(buffer);
                                objMesh.Normals.AddRange(vectors);
                            }
                            continue;
                        }

                        if (attribute.Name == "TEXCOORD")
                        {
                            if (numComponents != 2)
                            {
                                // ignore textcoords that arent 2
                                continue;
                            }
                            var vectors = ToVector2Array(buffer);
                            objMesh.TextureCoords.AddRange(vectors);
                        }
                    }

                    // Set index buffer
                    var startIndex = (int)drawCall.GetIntegerProperty("m_nStartIndex");
                    var indexCount = (int)drawCall.GetIntegerProperty("m_nIndexCount");
                    var indices    = ReadIndices(indexBuffer, startIndex, indexCount);
                    var newFaces   = indices.ChunkBy(3).Select(idxList => idxList.Select(idx => new ObjFaceVertex(idx + startingVertexCount)).ToList()).ToList();
                    objMesh.Faces.AddRange(newFaces);

                    var materialPath     = drawCall.GetProperty <string>("m_material");
                    var materialResource = VpkLoader.LoadFile(materialPath + "_c");
                    var renderMaterial   = (VMaterial)materialResource.DataBlock;
                    var matName          = Path.GetFileNameWithoutExtension(materialPath);
                    if (objMesh.Material == null)
                    {
                        objMesh.Material = ObjMaterial.FromVMaterial(renderMaterial, Path.GetFileNameWithoutExtension(materialPath), VpkLoader);
                    }
                    else if (matName != objMesh.Material.Name)
                    {
                        // throw new Exception("2 different mats in same object");
                    }
                }
            }
        }
Beispiel #22
0
 public override void Render(VMesh m, VVisualizer v)
 {
     v.SetMesh(m);
     v.Visualize();
 }
Beispiel #23
0
        public override GraphNode3D LoadNode(string path)
        {
            GraphEntity3D root = new GraphEntity3D();
            string        file = path;

            var e  = new Assimp.AssimpContext();
            var c1 = new Assimp.Configs.NormalSmoothingAngleConfig(45);

            e.SetConfig(c1);
            Console.WriteLine("Impporting:" + file);
            Assimp.Scene s = null;
            try
            {
                s = e.ImportFile(file, PostProcessSteps.CalculateTangentSpace | PostProcessSteps.GenerateSmoothNormals | PostProcessSteps.Triangulate | PostProcessSteps.GenerateNormals);
            }
            catch (AssimpException ae)
            {
                Console.WriteLine(ae);
                Console.WriteLine("Failed to import");
            }
            Console.WriteLine("Imported.");
            Dictionary <string, VMesh> ml = new Dictionary <string, VMesh>();
            List <VMesh> ml2 = new List <VMesh>();

            foreach (var m in s.Meshes)
            {
                var vm = new Material.Material3D();

                var m2 = new VMesh(m.VertexCount, m.GetIndices().Length);
                ml2.Add(m2);
                // ml.Add(m.Name, m2);

                m2.Mat = vm;
                // root.AddMesh(m2);
                m2.Name = m.Name;
                var         mat = s.Materials[m.MaterialIndex];
                TextureSlot t1;

                if (mat.GetMaterialTextureCount(TextureType.Diffuse) > 0)
                {
                    t1 = mat.GetMaterialTextures(TextureType.Diffuse)[0];


                    if (t1.FilePath != null)
                    {
                        vm.TCol = new Tex.Tex2D(IPath + t1.FilePath, false);
                        Console.WriteLine("TexLoaded");
                    }
                    if (true)
                    {
                        if (new FileInfo(t1.FilePath).Exists == true)
                        {
                            //  var tex = App.AppSal.CreateTex2D();
                            //  tex.Path = t1.FilePath;
                            // tex.Load();
                            //m2.DiffuseMap = tex;
                        }
                    }
                }
                for (int i = 0; i < m2.NumVertices; i++)
                {
                    var      v = m.Vertices[i];
                    var      n = m.Normals[i];
                    var      t = m.TextureCoordinateChannels[0];
                    Vector3D tan, bi;
                    if (m.Tangents != null && m.Tangents.Count > 0)
                    {
                        tan = m.Tangents[i];
                        bi  = m.BiTangents[i];
                    }
                    else
                    {
                        tan = new Vector3D(0, 0, 0);
                        bi  = new Vector3D(0, 0, 0);
                    }
                    if (t.Count() == 0)
                    {
                        m2.SetVertex(i, Cv(v), Cv(tan), Cv(bi), Cv(n), Cv2(t[i]));
                    }
                    else
                    {
                        m2.SetVertex(i, Cv(v), Cv(tan), Cv(bi), Cv(n), Cv2(t[i]));
                    }
                }
                int[]  id = m.GetIndices();
                int    fi = 0;
                uint[] nd = new uint[id.Length];
                for (int i = 0; i < id.Length; i++)
                {
                    nd[i] = (uint)id[i];
                }

                m2.Indices = nd;

                m2.Final();
            }

            ProcessNode(root, s.RootNode, ml2);


            return(root as GraphNode3D);
        }
Beispiel #24
0
        private Mesh CreateGltfMesh(string meshName, VMesh vmesh, ModelRoot model)
        {
            ProgressDialog.SetProgress($"Creating mesh: {meshName}");

            var data = vmesh.GetData();
            var vbib = vmesh.VBIB;

            var mesh = model.CreateMesh(meshName);

            mesh.Name = meshName;

            foreach (var sceneObject in data.GetArray("m_sceneObjects"))
            {
                foreach (var drawCall in sceneObject.GetArray("m_drawCalls"))
                {
                    var vertexBufferInfo  = drawCall.GetArray("m_vertexBuffers")[0]; // In what situation can we have more than 1 vertex buffer per draw call?
                    var vertexBufferIndex = (int)vertexBufferInfo.GetIntegerProperty("m_hBuffer");
                    var vertexBuffer      = vbib.VertexBuffers[vertexBufferIndex];

                    var indexBufferInfo  = drawCall.GetSubCollection("m_indexBuffer");
                    var indexBufferIndex = (int)indexBufferInfo.GetIntegerProperty("m_hBuffer");
                    var indexBuffer      = vbib.IndexBuffers[indexBufferIndex];

                    // Create one primitive per draw call
                    var primitive = mesh.CreatePrimitive();

                    // Avoid duplicate attribute names
                    var uniqueAttributes = vertexBuffer.Attributes.GroupBy(a => a.Name).Select(g => g.First());

                    // Set vertex attributes
                    foreach (var attribute in uniqueAttributes)
                    {
                        if (AccessorInfo.TryGetValue(attribute.Name, out var accessorInfo))
                        {
                            var buffer = ReadAttributeBuffer(vbib, vertexBuffer, attribute);

                            if (accessorInfo.NumComponents == 4)
                            {
                                var vectors = ToVector4Array(buffer);
                                primitive.WithVertexAccessor(accessorInfo.GltfAccessorName, vectors);
                            }
                            else if (attribute.Name == "NORMAL" && DrawCall.IsCompressedNormalTangent(drawCall))
                            {
                                var vectors = ToVector4Array(buffer);
                                var(normals, tangents) = DecompressNormalTangents(vectors);
                                primitive.WithVertexAccessor("NORMAL", normals);
                                primitive.WithVertexAccessor("TANGENT", tangents);
                            }
                            else if (accessorInfo.NumComponents == 3)
                            {
                                var vectors = ToVector3Array(buffer, true, accessorInfo.Resize);
                                primitive.WithVertexAccessor(accessorInfo.GltfAccessorName, vectors);
                            }
                            else if (accessorInfo.NumComponents == 2)
                            {
                                var vectors = ToVector2Array(buffer);
                                primitive.WithVertexAccessor(accessorInfo.GltfAccessorName, vectors);
                            }
                        }
                    }

                    // Set index buffer
                    var indices = ReadIndices(indexBuffer);

                    // For triangle primitives, the front face has to be in counter-clockwise (CCW) winding order.
                    for (var i = 0; i < indices.Length; i += 3)
                    {
                        var b = indices[i + 2];
                        indices[i + 2] = indices[i + 1];
                        indices[i + 1] = b;
                    }

                    primitive.WithIndicesAccessor(PrimitiveType.TRIANGLES, indices);

                    // Add material
                    var materialPath = drawCall.GetProperty <string>("m_material");

                    ProgressDialog.SetProgress($"Loading material: {materialPath}");

                    var materialResource = GuiContext.LoadFileByAnyMeansNecessary(materialPath + "_c");

                    if (materialResource == null)
                    {
                        continue;
                    }

                    var renderMaterial = (VMaterial)materialResource.DataBlock;

                    var materialNameTrimmed = Path.GetFileNameWithoutExtension(materialPath);
                    var bestMaterial        = GenerateGLTFMaterialFromRenderMaterial(renderMaterial, model, materialNameTrimmed);
                    primitive.WithMaterial(bestMaterial);
                }
            }

            return(mesh);
        }
Beispiel #25
0
    public void CreateMesh(object lod)
    {
        threadReady = false;

        VMesh mesh = new VMesh(this);

        for (int x = 0; x < map.size; x++)
        {
            for (int y = 0; y < map.size; y++)
            {
                for (int z = 0; z < map.size; z++)
                {
                    Vector3 pos    = new Vector3(x, y, z);
                    Color   blockC = map.GetBlock(pos);

                    if (blockC.a == 0)
                    {
                        continue;
                    }

                    Vector3 vertexpos = pos / blocksPerUnit;
                    mesh.SetDrawingColor(blockC);

                    if (map.GetBlock(pos + new Vector3(0, 1, 0)).a == 0)
                    {
                        //Top Face
                        mesh.AddQuad(
                            vertexpos + new Vector3(0, 1, 0) / blocksPerUnit,
                            vertexpos + new Vector3(0, 1, 1) / blocksPerUnit,
                            vertexpos + new Vector3(1, 1, 1) / blocksPerUnit,
                            vertexpos + new Vector3(1, 1, 0) / blocksPerUnit,
                            Vector3.up);
                    }
                    if (map.GetBlock(pos + new Vector3(0, -1, 0)).a == 0)
                    {
                        //Bottom Face
                        mesh.AddQuadFlipped(
                            vertexpos + new Vector3(0, 0, 0) / blocksPerUnit,
                            vertexpos + new Vector3(0, 0, 1) / blocksPerUnit,
                            vertexpos + new Vector3(1, 0, 1) / blocksPerUnit,
                            vertexpos + new Vector3(1, 0, 0) / blocksPerUnit,
                            Vector3.down);
                    }
                    if (map.GetBlock(pos + new Vector3(1, 0, 0)).a == 0)
                    {
                        //Right Face
                        mesh.AddQuadFlipped(
                            vertexpos + new Vector3(1, 0, 0) / blocksPerUnit,
                            vertexpos + new Vector3(1, 0, 1) / blocksPerUnit,
                            vertexpos + new Vector3(1, 1, 1) / blocksPerUnit,
                            vertexpos + new Vector3(1, 1, 0) / blocksPerUnit,
                            Vector3.right);
                    }
                    if (map.GetBlock(pos + new Vector3(-1, 0, 0)).a == 0)
                    {
                        //Left Face
                        mesh.AddQuad(
                            vertexpos + new Vector3(0, 0, 0) / blocksPerUnit,
                            vertexpos + new Vector3(0, 0, 1) / blocksPerUnit,
                            vertexpos + new Vector3(0, 1, 1) / blocksPerUnit,
                            vertexpos + new Vector3(0, 1, 0) / blocksPerUnit,
                            Vector3.left);
                    }
                    if (map.GetBlock(pos + new Vector3(0, 0, 1)).a == 0)
                    {
                        //Front Face
                        mesh.AddQuadFlipped(
                            vertexpos + new Vector3(0, 0, 1) / blocksPerUnit,
                            vertexpos + new Vector3(0, 1, 1) / blocksPerUnit,
                            vertexpos + new Vector3(1, 1, 1) / blocksPerUnit,
                            vertexpos + new Vector3(1, 0, 1) / blocksPerUnit,
                            Vector3.forward);
                    }
                    if (map.GetBlock(pos + new Vector3(0, 0, -1)).a == 0)
                    {
                        //Front Face
                        mesh.AddQuad(
                            vertexpos + new Vector3(0, 0, 0) / blocksPerUnit,
                            vertexpos + new Vector3(0, 1, 0) / blocksPerUnit,
                            vertexpos + new Vector3(1, 1, 0) / blocksPerUnit,
                            vertexpos + new Vector3(1, 0, 0) / blocksPerUnit,
                            Vector3.back);
                    }
                }
            }
        }

        mesh.GenArrays();
        this.mesh = mesh;

        VoxelWorld.QueueDirtyChunk(this);
    }
Beispiel #26
0
 public virtual void Release(VMesh m)
 {
 }
Beispiel #27
0
 public virtual void Bind(VMesh m, VVisualizer v)
 {
 }
Beispiel #28
0
 public void AddMesh(VMesh mesh)
 {
     Meshes.Add(mesh);
 }
        private Mesh CreateGltfMesh(string meshName, VMesh vmesh, ModelRoot model, bool includeJoints)
        {
            ProgressDialog.SetProgress($"Creating mesh: {meshName}");

            var data = vmesh.GetData();
            var vbib = vmesh.VBIB;

            var mesh = model.CreateMesh(meshName);

            mesh.Name = meshName;

            foreach (var sceneObject in data.GetArray("m_sceneObjects"))
            {
                foreach (var drawCall in sceneObject.GetArray("m_drawCalls"))
                {
                    var vertexBufferInfo  = drawCall.GetArray("m_vertexBuffers")[0]; // In what situation can we have more than 1 vertex buffer per draw call?
                    var vertexBufferIndex = (int)vertexBufferInfo.GetIntegerProperty("m_hBuffer");
                    var vertexBuffer      = vbib.VertexBuffers[vertexBufferIndex];

                    var indexBufferInfo  = drawCall.GetSubCollection("m_indexBuffer");
                    var indexBufferIndex = (int)indexBufferInfo.GetIntegerProperty("m_hBuffer");
                    var indexBuffer      = vbib.IndexBuffers[indexBufferIndex];

                    // Create one primitive per draw call
                    var primitive = mesh.CreatePrimitive();

                    // Avoid duplicate attribute names
                    var attributeCounters = new Dictionary <string, int>();

                    // Set vertex attributes
                    foreach (var attribute in vertexBuffer.Attributes)
                    {
                        attributeCounters.TryGetValue(attribute.Name, out var attributeCounter);
                        attributeCounters[attribute.Name] = attributeCounter + 1;
                        var accessorName = GetAccessorName(attribute.Name, attributeCounter);

                        var buffer        = ReadAttributeBuffer(vertexBuffer, attribute);
                        var numComponents = buffer.Length / vertexBuffer.Count;

                        if (attribute.Name == "BLENDINDICES")
                        {
                            if (!includeJoints)
                            {
                                continue;
                            }

                            var byteBuffer    = buffer.Select(f => (byte)f).ToArray();
                            var rawBufferData = new byte[buffer.Length];
                            System.Buffer.BlockCopy(byteBuffer, 0, rawBufferData, 0, rawBufferData.Length);

                            var bufferView = mesh.LogicalParent.UseBufferView(rawBufferData);
                            var accessor   = mesh.LogicalParent.CreateAccessor();
                            accessor.SetVertexData(bufferView, 0, buffer.Length / 4, DimensionType.VEC4, EncodingType.UNSIGNED_BYTE);

                            primitive.SetVertexAccessor(accessorName, accessor);

                            continue;
                        }

                        if (attribute.Name == "NORMAL" && DrawCall.IsCompressedNormalTangent(drawCall))
                        {
                            var vectors = ToVector4Array(buffer);
                            var(normals, tangents) = DecompressNormalTangents(vectors);
                            primitive.WithVertexAccessor("NORMAL", normals);
                            primitive.WithVertexAccessor("TANGENT", tangents);

                            continue;
                        }

                        if (attribute.Name == "BLENDINDICES")
                        {
                            var byteBuffer = buffer.Select(f => (byte)f).ToArray();
                            var bufferView = mesh.LogicalParent.UseBufferView(byteBuffer);
                            var accessor   = mesh.LogicalParent.CreateAccessor();
                            accessor.SetVertexData(bufferView, 0, buffer.Length / 4, DimensionType.VEC4, EncodingType.UNSIGNED_BYTE);

                            primitive.SetVertexAccessor(accessorName, accessor);

                            continue;
                        }

                        if (attribute.Name == "TEXCOORD" && numComponents != 2)
                        {
                            // We are ignoring some data, but non-2-component UVs cause failures in gltf consumers
                            continue;
                        }

                        switch (numComponents)
                        {
                        case 4:
                        {
                            var vectors = ToVector4Array(buffer);
                            primitive.WithVertexAccessor(accessorName, vectors);
                            break;
                        }

                        case 3:
                        {
                            var vectors = ToVector3Array(buffer);
                            primitive.WithVertexAccessor(accessorName, vectors);
                            break;
                        }

                        case 2:
                        {
                            var vectors = ToVector2Array(buffer);
                            primitive.WithVertexAccessor(accessorName, vectors);
                            break;
                        }

                        case 1:
                        {
                            primitive.WithVertexAccessor(accessorName, buffer);
                            break;
                        }

                        default:
                            throw new NotImplementedException($"Attribute \"{attribute.Name}\" has {numComponents} components");
                        }
                    }

                    // For some reason soruce models can have joints but no weights, check if that is the case
                    var jointAccessor = primitive.GetVertexAccessor("JOINTS_0");
                    if (jointAccessor != null && primitive.GetVertexAccessor("WEIGHTS_0") == null)
                    {
                        // If this occurs, give default weights
                        var defaultWeights = Enumerable.Repeat(Vector4.UnitX, jointAccessor.Count).ToList();
                        primitive.WithVertexAccessor("WEIGHTS_0", defaultWeights);
                    }

                    // Set index buffer
                    var startIndex = (int)drawCall.GetIntegerProperty("m_nStartIndex");
                    var indexCount = (int)drawCall.GetIntegerProperty("m_nIndexCount");
                    var indices    = ReadIndices(indexBuffer, startIndex, indexCount);
                    primitive.WithIndicesAccessor(PrimitiveType.TRIANGLES, indices);

                    // Add material
                    var materialPath = drawCall.GetProperty <string>("m_material");

                    ProgressDialog.SetProgress($"Loading material: {materialPath}");

                    var materialResource = GuiContext.LoadFileByAnyMeansNecessary(materialPath + "_c");

                    if (materialResource == null)
                    {
                        continue;
                    }

                    var renderMaterial = (VMaterial)materialResource.DataBlock;

                    var materialNameTrimmed = Path.GetFileNameWithoutExtension(materialPath);
                    var bestMaterial        = GenerateGLTFMaterialFromRenderMaterial(renderMaterial, model, materialNameTrimmed);
                    primitive.WithMaterial(bestMaterial);
                }
            }

            return(mesh);
        }