Exemplo n.º 1
0
        public static bool TryConvert(this UStaticMesh originalMesh, out CStaticMesh convertedMesh)
        {
            convertedMesh = new CStaticMesh();
            if (originalMesh.RenderData == null)
            {
                return(false);
            }

            convertedMesh.BoundingSphere = new FSphere(0f, 0f, 0f, originalMesh.RenderData.Bounds.SphereRadius / 2);
            convertedMesh.BoundingBox    = new FBox(
                originalMesh.RenderData.Bounds.Origin - originalMesh.RenderData.Bounds.BoxExtent,
                originalMesh.RenderData.Bounds.Origin + originalMesh.RenderData.Bounds.BoxExtent);

            foreach (var srcLod in originalMesh.RenderData.LODs)
            {
                if (srcLod.SkipLod)
                {
                    continue;
                }

                var numTexCoords = srcLod.VertexBuffer !.NumTexCoords;
                var numVerts     = srcLod.PositionVertexBuffer !.Verts.Length;
                if (numVerts == 0 && numTexCoords == 0)
                {
                    continue;
                }

                if (numTexCoords > Constants.MAX_MESH_UV_SETS)
                {
                    throw new ParserException($"Static mesh has too many UV sets ({numTexCoords})");
                }

                var staticMeshLod = new CStaticMeshLod
                {
                    NumTexCoords = numTexCoords,
                    HasNormals   = true,
                    HasTangents  = true,
                    Indices      = new Lazy <FRawStaticIndexBuffer>(srcLod.IndexBuffer !),
                    Sections     = new Lazy <CMeshSection[]>(() =>
                    {
                        var sections = new CMeshSection[srcLod.Sections.Length];
                        for (var j = 0; j < sections.Length; j++)
                        {
                            sections[j] = new CMeshSection(srcLod.Sections[j].MaterialIndex,
                                                           originalMesh.StaticMaterials?[srcLod.Sections[j].MaterialIndex].MaterialSlotName.Text, // materialName
                                                           originalMesh.Materials?[srcLod.Sections[j].MaterialIndex],                             // material
                                                           srcLod.Sections[j].FirstIndex,                                                         // firstIndex
                                                           srcLod.Sections[j].NumTriangles);                                                      // numFaces
                        }

                        return(sections);
                    })
                };

                staticMeshLod.AllocateVerts(numVerts);
                if (srcLod.ColorVertexBuffer !.NumVertices != 0)
                {
                    staticMeshLod.AllocateVertexColorBuffer();
                }

                for (var j = 0; j < numVerts; j++)
                {
                    var suv = srcLod.VertexBuffer.UV[j];
                    if (suv.Normal[1].Data != 0)
                    {
                        throw new ParserException("Not implemented: should only be used in UE3");
                    }

                    staticMeshLod.Verts[j].Position = srcLod.PositionVertexBuffer.Verts[j];
                    UnpackNormals(suv.Normal, staticMeshLod.Verts[j]);
                    staticMeshLod.Verts[j].UV.U = suv.UV[0].U;
                    staticMeshLod.Verts[j].UV.V = suv.UV[0].V;

                    for (var k = 1; k < numTexCoords; k++)
                    {
                        staticMeshLod.ExtraUV.Value[k - 1][j].U = suv.UV[k].U;
                        staticMeshLod.ExtraUV.Value[k - 1][j].V = suv.UV[k].V;
                    }

                    if (srcLod.ColorVertexBuffer.NumVertices != 0)
                    {
                        staticMeshLod.VertexColors ![j] = srcLod.ColorVertexBuffer.Data[j];
Exemplo n.º 2
0
        public static bool TryConvert(this UStaticMesh originalMesh, out CStaticMesh convertedMesh)
        {
            convertedMesh = new CStaticMesh();
            if (originalMesh.RenderData == null)
            {
                return(false);
            }

            convertedMesh.BoundingShere = new FSphere(0f, 0f, 0f, originalMesh.RenderData.Bounds.SphereRadius / 2);
            convertedMesh.BoundingBox   = new FBox(
                originalMesh.RenderData.Bounds.Origin - originalMesh.RenderData.Bounds.BoxExtent,
                originalMesh.RenderData.Bounds.Origin + originalMesh.RenderData.Bounds.BoxExtent);

            var numLods = originalMesh.RenderData.LODs.Length;

            convertedMesh.LODs = new CStaticMeshLod[numLods];
            for (var i = 0; i < convertedMesh.LODs.Length; i++)
            {
                if (originalMesh.RenderData.LODs[i] is not
                {
                    VertexBuffer: not null,
                    PositionVertexBuffer: not null,
                    ColorVertexBuffer: not null,
                    IndexBuffer: not null
                } srcLod)
                {
                    continue;
                }

                var numTexCoords = srcLod.VertexBuffer.NumTexCoords;
                var numVerts     = srcLod.PositionVertexBuffer.Verts.Length;
                if (numVerts == 0 && numTexCoords == 0 && i < numLods - 1)
                {
                    Log.Logger.Debug($"LOD {i} is stripped, skipping...");
                    continue;
                }

                if (numTexCoords > _MAX_MESH_UV_SETS)
                {
                    throw new ParserException($"Static mesh has too many UV sets ({numTexCoords})");
                }

                convertedMesh.LODs[i] = new CStaticMeshLod
                {
                    NumTexCoords = numTexCoords,
                    HasNormals   = true,
                    HasTangents  = true,
                    Indices      = new Lazy <FRawStaticIndexBuffer>(srcLod.IndexBuffer),
                    Sections     = new Lazy <CMeshSection[]>(() =>
                    {
                        var sections = new CMeshSection[srcLod.Sections.Length];
                        for (var j = 0; j < sections.Length; j++)
                        {
                            sections[j] = new CMeshSection(originalMesh.Materials?[srcLod.Sections[j].MaterialIndex],
                                                           srcLod.Sections[j].FirstIndex, srcLod.Sections[j].NumTriangles);
                        }
                        return(sections);
                    })
                };

                convertedMesh.LODs[i].AllocateVerts(numVerts);
                if (srcLod.ColorVertexBuffer.NumVertices != 0)
                {
                    convertedMesh.LODs[i].AllocateVertexColorBuffer();
                }

                for (var j = 0; j < numVerts; j++)
                {
                    var suv = srcLod.VertexBuffer.UV[j];
                    if (suv.Normal[1].Data != 0)
                    {
                        throw new ParserException("Not implemented: should only be used in UE3");
                    }

                    convertedMesh.LODs[i].Verts[j].Position = srcLod.PositionVertexBuffer.Verts[j];
                    UnpackNormals(suv.Normal, convertedMesh.LODs[i].Verts[j]);
                    convertedMesh.LODs[i].Verts[j].UV.U = suv.UV[0].U;
                    convertedMesh.LODs[i].Verts[j].UV.V = suv.UV[0].V;

                    for (var k = 1; k < numTexCoords; k++)
                    {
                        convertedMesh.LODs[i].ExtraUV.Value[k - 1][j].U = suv.UV[k].U;
                        convertedMesh.LODs[i].ExtraUV.Value[k - 1][j].V = suv.UV[k].V;
                    }

                    if (srcLod.ColorVertexBuffer.NumVertices != 0)
                        convertedMesh.LODs[i].VertexColors[j] = srcLod.ColorVertexBuffer.Data[j];
                }
            }

            convertedMesh.FinalizeMesh();
            return(true);
        }