private void ExportSkeletalMeshLod(CSkelMeshLod lod, List <CSkelMeshBone> bones, FArchiveWriter Ar, List <MaterialExporter>?materialExports, ETexturePlatform platform = ETexturePlatform.DesktopMobile) { var share = new CVertexShare(); var infHdr = new VChunkHeader(); share.Prepare(lod.Verts); foreach (var vert in lod.Verts) { var weightsHash = vert.PackedWeights; for (var i = 0; i < vert.Bone.Length; i++) { weightsHash ^= (uint)vert.Bone[i] << i; } share.AddVertex(vert.Position, vert.Normal, weightsHash); } ExportCommonMeshData(Ar, lod.Sections.Value, lod.Verts, lod.Indices.Value, share, materialExports, platform); ExportSkeletonData(Ar, bones); var numInfluences = 0; for (var i = 0; i < share.Points.Count; i++) { for (var j = 0; j < Constants.NUM_INFLUENCES_UE4; j++) { if (lod.Verts[share.VertToWedge.Value[i]].Bone[j] < 0) { break; } numInfluences++; } } infHdr.DataCount = numInfluences; infHdr.DataSize = 12; Ar.SerializeChunkHeader(infHdr, "RAWWEIGHTS"); for (var i = 0; i < share.Points.Count; i++) { var v = lod.Verts[share.VertToWedge.Value[i]]; var unpackedWeights = v.UnpackWeights(); for (var j = 0; j < Constants.NUM_INFLUENCES_UE4; j++) { if (v.Bone[j] < 0) { break; } Ar.Write(unpackedWeights[j]); Ar.Write(i); Ar.Write((int)v.Bone[j]); } } ExportVertexColors(Ar, lod.VertexColors, lod.NumVerts); ExportExtraUV(Ar, lod.ExtraUV.Value, lod.NumVerts, lod.NumTexCoords); }
public static void ExportSkelMeshSections(int index, CSkelMeshLod lod, CMeshSection sect, List <MaterialExporter>?materialExports, MeshBuilder <VERTEX, VertexColorXTextureX, VertexJoints4> mesh) { string materialName; if (sect.Material?.Load <UMaterialInterface>() is { } tex) { materialName = tex.Name; var materialExporter = new MaterialExporter(tex, true); materialExports?.Add(materialExporter); }
public Gltf(string name, CSkelMeshLod lod, List <CSkelMeshBone> bones, List <MaterialExporter>?materialExports) { var mesh = new MeshBuilder <VERTEX, VertexColorXTextureX, VertexJoints4>(name); for (var i = 0; i < lod.Sections.Value.Length; i++) { ExportSkelMeshSections(i, lod, lod.Sections.Value[i], materialExports, mesh); } var sceneBuilder = new SceneBuilder(); var armatureNodeBuilder = new NodeBuilder(name + ".ao"); var armature = CreateGltfSkeleton(bones, armatureNodeBuilder); sceneBuilder.AddSkinnedMesh(mesh, Matrix4x4.Identity, armature); Model = sceneBuilder.ToGltf2(); }
private void ExportSkeletalMeshLod(CSkelMeshLod lod, CSkelMeshBone[] bones, FCustomArchiveWriter writer, List <MaterialExporter>?materialExports) { var share = new CVertexShare(); var boneHdr = new VChunkHeader(); var infHdr = new VChunkHeader(); share.Prepare(lod.Verts); foreach (var vert in lod.Verts) { var weightsHash = vert.PackedWeights; for (var i = 0; i < vert.Bone.Length; i++) { weightsHash ^= (uint)vert.Bone[i] << i; } share.AddVertex(vert.Position, vert.Normal, weightsHash); } ExportCommonMeshData(writer, lod.Sections.Value, lod.Verts, lod.Indices.Value, share, materialExports); var numBones = bones.Length; boneHdr.DataCount = numBones; boneHdr.DataSize = 120; writer.SerializeChunkHeader(boneHdr, "REFSKELT"); for (var i = 0; i < numBones; i++) { var numChildren = 0; for (var j = 0; j < numBones; j++) { if (j != i && bones[j].ParentIndex == i) { numChildren++; } } var bone = new VBone { Name = bones[i].Name.Text, NumChildren = numChildren, ParentIndex = bones[i].ParentIndex, BonePos = new VJointPosPsk { Position = bones[i].Position, Orientation = bones[i].Orientation } }; // MIRROR_MESH bone.BonePos.Orientation.Y *= -1; bone.BonePos.Orientation.W *= -1; bone.BonePos.Position.Y *= -1; bone.Serialize(writer); } var numInfluences = 0; for (var i = 0; i < share.Points.Count; i++) { for (var j = 0; j < 4; j++) { if (lod.Verts[share.VertToWedge.Value[i]].Bone[j] < 0) { break; } numInfluences++; } } infHdr.DataCount = numInfluences; infHdr.DataSize = 12; writer.SerializeChunkHeader(infHdr, "RAWWEIGHTS"); for (var i = 0; i < share.Points.Count; i++) { var v = lod.Verts[share.VertToWedge.Value[i]]; var unpackedWeights = v.UnpackWeights(); for (var j = 0; j < 4; j++) { if (v.Bone[j] < 0) { break; } writer.Write(unpackedWeights[j]); writer.Write(i); writer.Write((int)v.Bone[j]); } } ExportVertexColors(writer, lod.VertexColors, lod.NumVerts); ExportExtraUV(writer, lod.ExtraUV.Value, lod.NumVerts, lod.NumTexCoords); }