Example #1
0
        unsafe private void ProcessMesh(FLVER2.Mesh mesh, FlverSubmesh dest)
        {
            var factory = Scene.Renderer.Factory;

            dest.Material = GPUMaterials[mesh.MaterialIndex];

            //var MeshVertices = VerticesPool.Rent(mesh.VertexCount);
            var vSize        = dest.Material.VertexSize;
            var meshVertices = Marshal.AllocHGlobal(mesh.VertexCount * (int)vSize);

            dest.PickingVertices = Marshal.AllocHGlobal(mesh.VertexCount * sizeof(Vector3));
            var pvhandle = new Span <Vector3>(dest.PickingVertices.ToPointer(), mesh.VertexCount);

            if (dest.Material.LayoutType == MeshLayoutType.LayoutSky)
            {
                FillVerticesNormalOnly(mesh, pvhandle, meshVertices);
            }
            else if (dest.Material.LayoutType == MeshLayoutType.LayoutUV2)
            {
                FillVerticesUV2(mesh, pvhandle, meshVertices);
            }
            else
            {
                FillVerticesStandard(mesh, pvhandle, meshVertices);
            }

            dest.VertexCount = mesh.VertexCount;

            dest.MeshFacesets = new List <FlverSubmesh.FlverSubmeshFaceSet>();
            var facesets         = mesh.FaceSets;
            var fsUploadsPending = facesets.Count();

            bool is32bit      = Flver.Header.Version > 0x20005 && mesh.VertexCount > 65535;
            int  indicesTotal = 0;

            ushort[] fs16 = null;
            int[]    fs32 = null;
            foreach (var faceset in facesets)
            {
                indicesTotal += faceset.Indices.Length;
            }
            if (is32bit)
            {
                fs32 = new int[indicesTotal];
            }
            else
            {
                fs16 = new ushort[indicesTotal];
            }

            int idxoffset = 0;

            foreach (var faceset in facesets)
            {
                if (faceset.Indices.Length == 0)
                {
                    continue;
                }

                //At this point they use 32-bit faceset vertex indices

                uint buffersize = (uint)faceset.IndicesCount * (is32bit ? 4u : 2u);
                var  indices    = faceset.TriangleStrip ? faceset.Triangulate(true).ToArray() : faceset.Indices.ToArray();
                var  newFaceSet = new FlverSubmesh.FlverSubmeshFaceSet()
                {
                    BackfaceCulling = faceset.CullBackfaces,
                    IsTriangleStrip = faceset.TriangleStrip,
                    //IndexBuffer = factory.CreateBuffer(new BufferDescription(buffersize, BufferUsage.IndexBuffer)),
                    IndexOffset = idxoffset,

                    IndexCount          = faceset.IndicesCount,
                    Is32Bit             = is32bit,
                    PickingIndicesCount = indices.Length,
                    //PickingIndices = Marshal.AllocHGlobal(indices.Length * 4),
                };
                fixed(void *iptr = indices)
                {
                    //Unsafe.CopyBlock(newFaceSet.PickingIndices.ToPointer(), iptr, (uint)indices.Length * 4);
                }

                if ((faceset.Flags & FLVER2.FaceSet.FSFlags.LodLevel1) > 0)
                {
                    newFaceSet.LOD = 1;
                    //HasNoLODs = false;
                    newFaceSet.IsMotionBlur = false;
                }
                else if ((faceset.Flags & FLVER2.FaceSet.FSFlags.LodLevel2) > 0)
                {
                    newFaceSet.LOD = 2;
                    //HasNoLODs = false;
                    newFaceSet.IsMotionBlur = false;
                }

                if ((faceset.Flags & FLVER2.FaceSet.FSFlags.MotionBlur) > 0)
                {
                    newFaceSet.IsMotionBlur = true;
                }

                if (is32bit)
                {
                    for (int i = 0; i < faceset.Indices.Length; i++)
                    {
                        if (faceset.Indices[i] == 0xFFFF && faceset.Indices[i] > mesh.Vertices.Length)
                        {
                            fs32[newFaceSet.IndexOffset + i] = -1;
                        }
                        else
                        {
                            fs32[newFaceSet.IndexOffset + i] = faceset.Indices[i];
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < faceset.Indices.Length; i++)
                    {
                        if (faceset.Indices[i] == 0xFFFF && faceset.Indices[i] > mesh.Vertices.Length)
                        {
                            fs16[newFaceSet.IndexOffset + i] = 0xFFFF;
                        }
                        else
                        {
                            fs16[newFaceSet.IndexOffset + i] = (ushort)faceset.Indices[i];
                        }
                    }
                }

                dest.MeshFacesets.Add(newFaceSet);
                idxoffset += faceset.Indices.Length;
            }

            dest.Bounds = BoundingBox.CreateFromPoints((Vector3 *)dest.PickingVertices.ToPointer(), dest.VertexCount, 12, Quaternion.Identity, Vector3.Zero, Vector3.One);

            uint vbuffersize = (uint)mesh.VertexCount * (uint)vSize;

            dest.GeomBuffer = Scene.Renderer.GeometryBufferAllocator.Allocate(vbuffersize, (uint)indicesTotal * (is32bit ? 4u : 2u), (int)vSize, 4, (h) =>
            {
                h.FillVBuffer(meshVertices, vSize * (uint)mesh.VertexCount, () =>
                {
                    Marshal.FreeHGlobal(meshVertices);
                });
                if (is32bit)
                {
                    h.FillIBuffer(fs32);
                }
                else
                {
                    h.FillIBuffer(fs16);
                }
            });

            facesets = null;

            if (CaptureMaterialLayouts)
            {
                lock (_matLayoutLock)
                {
                    if (!MaterialLayouts.ContainsKey(dest.Material.MaterialName))
                    {
                        MaterialLayouts.Add(dest.Material.MaterialName, Flver.BufferLayouts[mesh.VertexBuffers[0].LayoutIndex]);
                    }
                }
            }

            if (mesh.DefaultBoneIndex != -1 && mesh.DefaultBoneIndex < Bones.Count)
            {
                dest.LocalTransform = Utils.GetBoneObjectMatrix(Bones[mesh.DefaultBoneIndex], Bones);
            }

            Marshal.FreeHGlobal(dest.PickingVertices);
        }
Example #2
0
        unsafe private void ProcessMesh(FLVER0.Mesh mesh, FlverSubmesh dest)
        {
            var factory = Scene.Renderer.Factory;

            dest.Material = GPUMaterials[mesh.MaterialIndex];

            //var MeshVertices = VerticesPool.Rent(mesh.VertexCount);
            var vSize        = dest.Material.VertexSize;
            var meshVertices = Marshal.AllocHGlobal(mesh.Vertices.Count * (int)vSize);

            dest.PickingVertices = Marshal.AllocHGlobal(mesh.Vertices.Count * sizeof(Vector3));
            var pvhandle = new Span <Vector3>(dest.PickingVertices.ToPointer(), mesh.Vertices.Count);

            if (dest.Material.LayoutType == MeshLayoutType.LayoutSky)
            {
                FillVerticesNormalOnly(mesh, pvhandle, meshVertices);
            }
            else if (dest.Material.LayoutType == MeshLayoutType.LayoutUV2)
            {
                FillVerticesUV2(mesh, pvhandle, meshVertices);
            }
            else
            {
                FillVerticesStandard(mesh, pvhandle, meshVertices);
            }

            dest.VertexCount = mesh.Vertices.Count;

            dest.MeshFacesets = new List <FlverSubmesh.FlverSubmeshFaceSet>();

            bool is32bit      = false;//FlverDeS.Version > 0x20005 && mesh.Vertices.Count > 65535;
            int  indicesTotal = 0;

            ushort[] fs16 = null;
            int[]    fs32 = null;

            int idxoffset = 0;

            if (mesh.VertexIndices.Count != 0)
            {
                var  indices    = mesh.Triangulate(FlverDeS.Version).ToArray();
                uint buffersize = (uint)indices.Length * (is32bit ? 4u : 2u);

                indicesTotal = indices.Length;
                if (is32bit)
                {
                    fs32 = new int[indicesTotal];
                }
                else
                {
                    fs16 = new ushort[indicesTotal];
                }

                var newFaceSet = new FlverSubmesh.FlverSubmeshFaceSet()
                {
                    BackfaceCulling = true,
                    IsTriangleStrip = false,
                    //IndexBuffer = factory.CreateBuffer(new BufferDescription(buffersize, BufferUsage.IndexBuffer)),
                    IndexOffset = idxoffset,

                    IndexCount          = indices.Length,
                    Is32Bit             = is32bit,
                    PickingIndicesCount = indices.Length,
                    //PickingIndices = Marshal.AllocHGlobal(indices.Length * 4),
                };
                fixed(void *iptr = indices)
                {
                    //Unsafe.CopyBlock(newFaceSet.PickingIndices.ToPointer(), iptr, (uint)indices.Length * 4);
                }

                if (is32bit)
                {
                    for (int i = 0; i < indices.Length; i++)
                    {
                        if (indices[i] == 0xFFFF && indices[i] > mesh.Vertices.Count)
                        {
                            fs32[newFaceSet.IndexOffset + i] = -1;
                        }
                        else
                        {
                            fs32[newFaceSet.IndexOffset + i] = indices[i];
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < indices.Length; i++)
                    {
                        if (indices[i] == 0xFFFF && indices[i] > mesh.Vertices.Count)
                        {
                            fs16[newFaceSet.IndexOffset + i] = 0xFFFF;
                        }
                        else
                        {
                            fs16[newFaceSet.IndexOffset + i] = (ushort)indices[i];
                        }
                    }
                }

                dest.MeshFacesets.Add(newFaceSet);
            }

            dest.Bounds = BoundingBox.CreateFromPoints((Vector3 *)dest.PickingVertices.ToPointer(), dest.VertexCount, 12, Quaternion.Identity, Vector3.Zero, Vector3.One);

            uint vbuffersize = (uint)mesh.Vertices.Count * (uint)vSize;

            dest.GeomBuffer = Scene.Renderer.GeometryBufferAllocator.Allocate(vbuffersize, (uint)indicesTotal * (is32bit ? 4u : 2u), (int)vSize, 4, (h) =>
            {
                h.FillVBuffer(meshVertices, vSize * (uint)mesh.Vertices.Count, () =>
                {
                    Marshal.FreeHGlobal(meshVertices);
                });
                if (is32bit)
                {
                    h.FillIBuffer(fs32);
                }
                else
                {
                    h.FillIBuffer(fs16);
                }
            });

            if (CaptureMaterialLayouts)
            {
                lock (_matLayoutLock)
                {
                    if (!MaterialLayouts.ContainsKey(dest.Material.MaterialName))
                    {
                        MaterialLayouts.Add(dest.Material.MaterialName, Flver.BufferLayouts[mesh.LayoutIndex]);
                    }
                }
            }
        }