示例#1
0
        /// <summary>
        /// Creates a preview of the given <see cref="SkeletalMesh"/>.
        /// </summary>
        /// <param name="Device">The Direct3D device to use for buffer creation.</param>
        /// <param name="m">The mesh to generate a preview for.</param>
        /// <param name="texcache">The texture cache for loading textures.</param>
        public ModelPreview(Device Device, SkeletalMesh m, PreviewTextureCache texcache, PackageCache assetCache, PreloadedModelData preloadedData = null)
        {
            // STEP 1: MATERIALS
            if (preloadedData == null)
            {
                for (int i = 0; i < m.Materials.Length; i++)
                {
                    UIndex materialUIndex        = m.Materials[i];
                    MaterialInstanceConstant mat = null;
                    if (materialUIndex.value > 0)
                    {
                        mat = new MaterialInstanceConstant(m.Export.FileRef.GetUExport(materialUIndex.value));
                    }
                    else if (materialUIndex.value < 0)
                    {
                        // The material instance is an import!
                        ImportEntry matImport     = m.Export.FileRef.GetImport(materialUIndex.value);
                        var         externalAsset = EntryImporter.ResolveImport(matImport, null, assetCache);
                        if (externalAsset != null)
                        {
                            mat = new MaterialInstanceConstant(externalAsset);
                        }
                    }

                    if (mat != null)
                    {
                        ModelPreviewMaterial material;
                        // TODO: pick what material class best fits based on what properties the
                        // MaterialInstanceConstant mat has.
                        // For now, just use the default material.
                        material = new TexturedPreviewMaterial(texcache, mat, assetCache);
                        AddMaterial(material.Properties["Name"], material);
                    }
                }
            }
            else
            {
                //Preloaded
                //sections = preloadedData.sections;
                var uniqueMaterials = preloadedData.texturePreviewMaterials.Select(x => x.MaterialExport).Distinct();
                foreach (var mat in uniqueMaterials)
                {
                    var material = new TexturedPreviewMaterial(texcache, new MaterialInstanceConstant(mat), assetCache, preloadedData.texturePreviewMaterials);
                    AddMaterial(mat.ObjectName.Name, material);
                }
            }

            // STEP 2: LODS
            foreach (var lodmodel in m.LODModels)
            {
                // Vertices
                List <WorldVertex> vertices = new List <WorldVertex>(m.Export.Game == MEGame.ME1 ? lodmodel.ME1VertexBufferGPUSkin.Length : lodmodel.VertexBufferGPUSkin.VertexData.Length);
                if (m.Export.Game == MEGame.ME1)
                {
                    foreach (var vertex in lodmodel.ME1VertexBufferGPUSkin)
                    {
                        vertices.Add(new WorldVertex(new Vector3(-vertex.Position.X, vertex.Position.Z, vertex.Position.Y), Vector3.Zero, new Vector2(vertex.UV.X, vertex.UV.Y)));
                    }
                }
                else
                {
                    foreach (var vertex in lodmodel.VertexBufferGPUSkin.VertexData)
                    {
                        vertices.Add(new WorldVertex(new Vector3(-vertex.Position.X, vertex.Position.Z, vertex.Position.Y), Vector3.Zero, new Vector2(vertex.UV.X, vertex.UV.Y)));
                    }
                }
                // Triangles
                List <Triangle> triangles = new List <Triangle>(lodmodel.IndexBuffer.Length / 3);
                for (int i = 0; i < lodmodel.IndexBuffer.Length; i += 3)
                {
                    triangles.Add(new Triangle(lodmodel.IndexBuffer[i], lodmodel.IndexBuffer[i + 1], lodmodel.IndexBuffer[i + 2]));
                }
                WorldMesh mesh = new WorldMesh(Device, triangles, vertices);
                // Sections
                List <ModelPreviewSection> sections = new List <ModelPreviewSection>();
                foreach (var section in lodmodel.Sections)
                {
                    if (section.MaterialIndex < Materials.Count)
                    {
                        sections.Add(new ModelPreviewSection(Materials.Keys.ElementAt(section.MaterialIndex), section.BaseIndex, (uint)section.NumTriangles));
                    }
                }
                LODs.Add(new ModelPreviewLOD(mesh, sections));
            }
        }
示例#2
0
        public static StaticMesh ConvertToME3StaticMesh(this SkeletalMesh skeletalMesh)
        {
            StaticLODModel lodModel    = skeletalMesh.LODModels[0];
            uint           numVertices = lodModel.NumVertices;
            var            stm         = new StaticMesh
            {
                Bounds    = skeletalMesh.Bounds,
                BodySetup = new UIndex(0),
                LODModels = new[] { new StaticMeshRenderData
                                    {
                                        IndexBuffer                 = lodModel.IndexBuffer.TypedClone(),
                                        NumVertices                 = numVertices,
                                        Edges                       = new MeshEdge[0],
                                        RawTriangles                = new StaticMeshTriangle[0],
                                        ColorVertexBuffer           = new ColorVertexBuffer(),
                                        ShadowTriangleDoubleSided   = new byte[0],
                                        WireframeIndexBuffer        = new ushort[0],
                                        ShadowExtrusionVertexBuffer = new ExtrusionVertexBuffer
                                        {
                                            Stride     = 4,
                                            VertexData = new float[0]
                                        },
                                        PositionVertexBuffer = new PositionVertexBuffer
                                        {
                                            NumVertices = numVertices,
                                            Stride      = 12,
                                            VertexData  = new Vector3[numVertices]
                                        },
                                        VertexBuffer = new StaticMeshVertexBuffer
                                        {
                                            bUseFullPrecisionUVs = false,
                                            NumTexCoords         = 1,
                                            NumVertices          = numVertices,
                                            VertexData           = new StaticMeshVertexBuffer.StaticMeshFullVertex[numVertices]
                                        },
                                        Elements = lodModel.Sections.Select(sec =>
                        {
                            var indices = lodModel.IndexBuffer.Skip((int)sec.BaseIndex).Take(sec.NumTriangles * 3).ToList();
                            return(new StaticMeshElement
                            {
                                bEnableShadowCasting = true,
                                EnableCollision = true,
                                OldEnableCollision = true,
                                FirstIndex = sec.BaseIndex,
                                NumTriangles = (uint)sec.NumTriangles,
                                MaterialIndex = sec.MaterialIndex,
                                Material = skeletalMesh.Materials[sec.MaterialIndex],
                                Fragments = new FragmentRange[0],
                                MinVertexIndex = indices.Min(),
                                MaxVertexIndex = indices.Max()
                            });
                        }).ToArray()
                                    } },
                InternalVersion = 18,
                LightingGuid    = Guid.NewGuid()
            };

            Vector3[] posVertData = stm.LODModels[0].PositionVertexBuffer.VertexData;
            StaticMeshVertexBuffer.StaticMeshFullVertex[] stmVertData = stm.LODModels[0].VertexBuffer.VertexData;
            if (lodModel.ME1VertexBufferGPUSkin != null)
            {
                for (int i = 0; i < lodModel.ME1VertexBufferGPUSkin.Length; i++)
                {
                    SoftSkinVertex vert = lodModel.ME1VertexBufferGPUSkin[i];
                    posVertData[i] = vert.Position;
                    stmVertData[i] = new StaticMeshVertexBuffer.StaticMeshFullVertex
                    {
                        HalfPrecisionUVs = new Vector2DHalf[] { vert.UV },
                        TangentX         = vert.TangentX,
                        TangentZ         = vert.TangentZ
                    };
                }
            }
            else
            {
                for (int i = 0; i < lodModel.VertexBufferGPUSkin.VertexData.Length; i++)
                {
                    GPUSkinVertex vert = lodModel.VertexBufferGPUSkin.VertexData[i];
                    posVertData[i] = vert.Position;
                    stmVertData[i] = new StaticMeshVertexBuffer.StaticMeshFullVertex
                    {
                        HalfPrecisionUVs = new[] { vert.UV },
                        TangentX         = vert.TangentX,
                        TangentZ         = vert.TangentZ
                    };
                }
            }
            var tris = new kDOPCollisionTriangle[lodModel.IndexBuffer.Length / 3];

            for (int i = 0, elIdx = 0, triCount = 0; i < lodModel.IndexBuffer.Length; i += 3, ++triCount)
            {
                if (triCount > lodModel.Sections[elIdx].NumTriangles)
                {
                    triCount = 0;
                    ++elIdx;
                }
                tris[i / 3] = new kDOPCollisionTriangle(lodModel.IndexBuffer[i], lodModel.IndexBuffer[i + 1], lodModel.IndexBuffer[i + 2],
                                                        lodModel.Sections[elIdx].MaterialIndex);
            }

            stm.kDOPTreeME3UDK = KDOPTreeBuilder.ToCompact(tris, stm.LODModels[0].PositionVertexBuffer.VertexData);

            return(stm);
        }