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];
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); }