Beispiel #1
0
        internal FSkelMeshSection(BinaryReader reader, FNameEntrySerialized[] name_map)
        {
            var flags = new FStripDataFlags(reader);

            material_index = reader.ReadUInt16();
            base_index     = reader.ReadUInt32();
            num_triangles  = reader.ReadUInt32();

            var _recompute_tangent = reader.ReadUInt32() != 0;
            var _cast_shadow       = reader.ReadUInt32() != 0;

            base_vertex_index  = reader.ReadUInt32();
            cloth_mapping_data = reader.ReadTArray(() => new FApexClothPhysToRenderVertData(reader));
            bool HasClothData = cloth_mapping_data.Length > 0;

            bone_map            = reader.ReadTArray(() => reader.ReadUInt16());
            num_vertices        = reader.ReadInt32();
            max_bone_influences = reader.ReadInt32();
            var _correspond_cloth_asset_index = reader.ReadInt16();

            clothing_data = new FClothingSectionData(reader);
            var _vertex_buffer = new FDuplicatedVerticesBuffer(reader);

            disabled = reader.ReadUInt32() != 0;
        }
Beispiel #2
0
        //public FStaticMeshVertexDataUV? uvs;

        public FStaticMeshVertexBuffer(BinaryReader reader)
        {
            high_precision_tangent_basis = false;

            var flags = new FStripDataFlags(reader);

            num_tex_coords               = reader.ReadInt32();
            num_vertices                 = reader.ReadInt32();
            full_precision_uvs           = reader.ReadInt32() != 0;
            high_precision_tangent_basis = reader.ReadInt32() != 0;

            if (!flags.server_data_stripped)
            {
                int ItemSize, ItemCount;
                uv = new FStaticMeshUVItem4[num_vertices];

                // Tangents
                ItemSize  = reader.ReadInt32();
                ItemCount = reader.ReadInt32();
                if (ItemCount != num_vertices)
                {
                    throw new FileLoadException("Invalid item count/num_vertices at pos " + reader.BaseStream.Position);
                }
                var pos = reader.BaseStream.Position;
                for (int i = 0; i < num_vertices; i++)
                {
                    uv[i].SerializeTangents(reader, high_precision_tangent_basis);
                }
                if (reader.BaseStream.Position - pos != ItemCount * ItemSize)
                {
                    throw new FileLoadException("Didn't read static mesh uvs correctly at pos " + reader.BaseStream.Position);
                }

                // Texture coordinates
                ItemSize  = reader.ReadInt32();
                ItemCount = reader.ReadInt32();
                if (ItemCount != num_vertices * num_tex_coords)
                {
                    throw new FileLoadException("Invalid item count/num_vertices at pos " + reader.BaseStream.Position);
                }
                pos = reader.BaseStream.Position;
                for (int i = 0; i < num_vertices; i++)
                {
                    uv[i].SerializeTexcoords(reader, num_tex_coords, full_precision_uvs);
                }
                if (reader.BaseStream.Position - pos != ItemCount * ItemSize)
                {
                    throw new FileLoadException("Didn't read static mesh texcoords correctly at pos " + reader.BaseStream.Position);
                }
            }
            else
            {
                uv = null;
            }
        }
Beispiel #3
0
        internal FStaticLODModel(BinaryReader reader, FNameEntrySerialized[] name_map, bool has_vertex_colors)
        {
            var flags = new FStripDataFlags(reader);

            Sections          = reader.ReadTArray(() => new FSkelMeshSection(reader, name_map));
            Indices           = new FMultisizeIndexContainer(reader);
            ActiveBoneIndices = reader.ReadTArray(() => reader.ReadInt16());
            RequiredBones     = reader.ReadTArray(() => reader.ReadInt16());

            if (flags.server_data_stripped || flags.class_data_stripped(2))
            {
                throw new FileLoadException("Could not read FSkelMesh, no renderable data");
            }

            var position_vertex_buffer    = new FPositionVertexBuffer(reader);
            var static_mesh_vertex_buffer = new FStaticMeshVertexBuffer(reader);
            var skin_weight_vertex_buffer = new FSkinWeightVertexBuffer(reader);

            if (has_vertex_colors)
            {
                var colour_vertex_buffer = new FColorVertexBuffer(reader);
            }

            AdjacencyIndexBuffer = default;
            if (!flags.class_data_stripped(1))
            {
                AdjacencyIndexBuffer = new FMultisizeIndexContainer(reader);
            }

            ClothVertexBuffer = default;
            if (HasClothData(Sections))
            {
                ClothVertexBuffer = new FSkeletalMeshVertexClothBuffer(reader);
            }

            SkinWeightProfilesData = new FSkinWeightProfilesData(reader, name_map);

            VertexBufferGPUSkin = new FSkeletalMeshVertexBuffer();
            VertexBufferGPUSkin.bUseFullPrecisionUVs = true;
            NumVertices  = position_vertex_buffer.num_verts;
            NumTexCoords = static_mesh_vertex_buffer.num_tex_coords;

            VertexBufferGPUSkin.VertsFloat = new FGPUVert4Float[NumVertices];
            for (int i = 0; i < NumVertices; i++)
            {
                var V  = new FGPUVert4Float();
                var SV = static_mesh_vertex_buffer.uv[i];
                V.Pos    = position_vertex_buffer.verts[i];
                V.Infs   = skin_weight_vertex_buffer.weights[i];
                V.Normal = SV.Normal; // i mean, we're not using it for anything else, are we?
                V.UV     = SV.UV;
                VertexBufferGPUSkin.VertsFloat[i] = V;
            }
        }
Beispiel #4
0
        public FColorVertexBuffer(BinaryReader reader)
        {
            var flags = new FStripDataFlags(reader);

            stride    = reader.ReadInt32();
            num_verts = reader.ReadInt32();
            colors    = null;
            if (!flags.server_data_stripped && num_verts > 0)
            {
                var _element_size = reader.ReadInt32();
                colors = reader.ReadTArray(() => new FColor(reader));
            }
        }
        public FSkinWeightVertexBuffer(BinaryReader reader)
        {
            var flags = new FStripDataFlags(reader);

            var bExtraBoneInfluences = reader.ReadInt32() != 0;
            var num_vertices         = reader.ReadInt32();

            if (flags.server_data_stripped)
            {
                weights = null;
                return;
            }

            var _element_size  = reader.ReadInt32();
            var num_influences = bExtraBoneInfluences ? 8 : 4;

            weights = reader.ReadTArray(() => new FSkinWeightInfo(reader, num_influences));
        }
Beispiel #6
0
        public FSkeletalMeshVertexClothBuffer(BinaryReader reader)
        {
            var flags = new FStripDataFlags(reader);

            if (!flags.server_data_stripped)
            {
                // umodel: https://github.com/gildor2/UModel/blob/9a1fe8c77d136f018ba18c9e5c445fdcc5f374ae/Unreal/UnMesh4.cpp#L924
                //         https://github.com/gildor2/UModel/blob/39c635c13d61616297fb3e47f33e3fc20259626e/Unreal/UnCoreSerialize.cpp#L320
                // ue4: https://github.com/EpicGames/UnrealEngine/blob/master/Engine/Source/Runtime/Engine/Private/SkeletalMeshLODRenderData.cpp#L758
                //      https://github.com/EpicGames/UnrealEngine/blob/master/Engine/Source/Runtime/Engine/Public/Rendering/SkeletalMeshLODRenderData.h#L119

                int elem_size = reader.ReadInt32(); // umodel has this, might want to actually serialize this like how ue4 has it
                int count     = reader.ReadInt32();
                reader.BaseStream.Seek(elem_size * count, SeekOrigin.Current);

                cloth_index_mapping = reader.ReadTArray(() => reader.ReadUInt64());
            }

            cloth_index_mapping = null;
        }
Beispiel #7
0
        internal USkeletalMesh(BinaryReader reader, FNameEntrySerialized[] name_map, FObjectImport[] import_map)
        {
            BaseObject = new UObject(reader, name_map, import_map, "SkeletalMesh", true);
            bool has_vertex_colors = false;

            foreach (var prop in BaseObject.properties)
            {
                if (prop.name == "bHasVertexColors" && prop.tag == FPropertyTagType.BoolProperty)
                {
                    has_vertex_colors = (bool)prop.tag_data;
                }
                else if (prop.name == "LODInfo")
                {
                    var data = ((UScriptArray)prop.tag_data).data;
                    LODInfo = new FSkeletalMeshLODInfo[data.Length];
                    for (int i = 0; i < data.Length; i++)
                    {
                        var info = (UScriptStruct)data[i];
                        if (info.struct_name != "SkeletalMeshLODInfo")
                        {
                            throw new FileLoadException("Invalid lod info type");
                        }
                        var props   = ((FStructFallback)info.struct_type).properties;
                        var newInfo = new FSkeletalMeshLODInfo();
                        foreach (var lodProp in props)
                        {
                            switch (lodProp.name)
                            {
                            case "DisplayFactor":
                                newInfo.DisplayFactor = (float)lodProp.tag_data;
                                break;

                            case "LODHysteresis":
                                newInfo.LODHysteresis = (float)lodProp.tag_data;
                                break;

                            case "LODMaterialMap":
                                newInfo.LODMaterialMap = ((UScriptArray)lodProp.tag_data).data.Cast <int>().ToArray();
                                break;

                            case "bEnableShadowCasting":
                                newInfo.bEnableShadowCasting = ((UScriptArray)lodProp.tag_data).data.Cast <bool>().ToArray();
                                break;
                            }
                        }
                        LODInfo[i] = newInfo;
                    }
                }
            }
            var flags = new FStripDataFlags(reader);

            Bounds      = new FBoxSphereBounds(reader);
            Materials   = reader.ReadTArray(() => new FSkeletalMaterial(reader, name_map, import_map));
            RefSkeleton = new FReferenceSkeleton(reader, name_map);

            if (!flags.editor_data_stripped)
            {
                Console.WriteLine("Editor data still present!");
            }

            if (reader.ReadUInt32() == 0)
            {
                throw new FileLoadException("No cooked data");
            }
            LODModels = reader.ReadTArray(() => new FStaticLODModel(reader, name_map, has_vertex_colors));

            uint serialize_guid = reader.ReadUInt32();

            MaterialAssets = new string[Materials.Length];
            for (int i = 0; i < Materials.Length; i++)
            {
                if (Materials[i].Material.import == null)
                {
                    continue;
                }
                for (int j = 0; j < import_map.Length; j++)
                {
                    if (import_map[j].class_name != "MaterialInstanceConstant" && import_map[j].object_name.EndsWith(Materials[i].Material.import))
                    {
                        MaterialAssets[i] = import_map[j].object_name;
                        break;
                    }
                }
            }
        }