Beispiel #1
0
 internal RWSceneStruct(RWScene scene)
     : base(new RWNodeFactory.RWNodeInfo { Parent = scene, Type = RWNodeType.Struct, Version = ExportVersion })
 {
     _drawCallCount = scene.DrawCalls.Count;
     _lightCount = 0;
     _cameraCount = 0;
 }
Beispiel #2
0
 /***************/
 /* Constructor */
 /***************/
 public RWSceneWrapper(string text, RWScene scene) : base(text, scene, SupportedFileType.RWScene, true)
 {
     m_isModel = true;
     m_canRename = false;
     m_canAdd = true;
     InitializeContextMenuStrip();
 }
Beispiel #3
0
        public static Assimp.Scene ToAssimpScene(RWScene scene)
        {
            Assimp.Scene aiScene = new Assimp.Scene();

            int drawCallIdx = 0;
            int materialIdx = 0;
            int totalSplitIdx = 0;
            List<int> meshStartIndices = new List<int>();
            foreach (RWDrawCall drawCall in scene.DrawCalls)
            {
                meshStartIndices.Add(totalSplitIdx);
                var mesh = scene.Meshes[drawCall.MeshIndex];
                var node = scene.Nodes[drawCall.NodeIndex];

                int splitIdx = 0;
                foreach (RWMeshMaterialSplit split in mesh.MaterialSplitData.MaterialSplits)
                {
                    Assimp.Mesh aiMesh = new Assimp.Mesh(Assimp.PrimitiveType.Triangle);
                    aiMesh.Name = string.Format("DrawCall{0}_Split{1}", drawCallIdx.ToString("00"), splitIdx.ToString("00"));
                    aiMesh.MaterialIndex = split.MaterialIndex + materialIdx;

                    // get split indices
                    int[] indices = split.Indices;
                    if (mesh.MaterialSplitData.PrimitiveType == RWPrimitiveType.TriangleStrip)
                        indices = MeshUtilities.ToTriangleList(indices, true);

                    // pos & nrm
                    for (int i = 0; i < indices.Length; i++)
                    {
                        if (mesh.HasVertices)
                        {
                            var vert = Vector3.Transform(mesh.Vertices[indices[i]], node.WorldTransform);
                            aiMesh.Vertices.Add(vert.ToAssimpVector3D());
                        }
                        if (mesh.HasNormals)
                        {
                            var nrm = Vector3.TransformNormal(mesh.Normals[indices[i]], node.WorldTransform);
                            aiMesh.Normals.Add(nrm.ToAssimpVector3D());
                        }
                    }

                    // tex coords
                    if (mesh.HasTexCoords)
                    {
                        for (int i = 0; i < mesh.TextureCoordinateChannelCount; i++)
                        {
                            List<Assimp.Vector3D> texCoordChannel = new List<Assimp.Vector3D>();

                            for (int j = 0; j < indices.Length; j++)
                            {
                                texCoordChannel.Add(mesh.TextureCoordinateChannels[i][indices[j]].ToAssimpVector3D(0));
                            }

                            aiMesh.TextureCoordinateChannels[i] = texCoordChannel;
                        }
                    }

                    // colors
                    if (mesh.HasColors)
                    {
                        List<Assimp.Color4D> vertColorChannel = new List<Assimp.Color4D>();

                        for (int i = 0; i < indices.Length; i++)
                        {
                            var color = mesh.Colors[indices[i]];
                            vertColorChannel.Add(new Assimp.Color4D(color.R / 255f, color.G / 255f, color.B / 255f, color.A / 255f));
                        }

                        aiMesh.VertexColorChannels[0] = vertColorChannel;
                    }

                    // generate temporary face indices
                    int[] tempIndices = new int[aiMesh.VertexCount];
                    for (int i = 0; i < aiMesh.VertexCount; i++)
                        tempIndices[i] = i;

                    aiMesh.SetIndices(tempIndices, 3);

                    // add the mesh to the list
                    aiScene.Meshes.Add(aiMesh);

                    splitIdx++;
                }

                totalSplitIdx += splitIdx;

                foreach (RWMaterial mat in mesh.Materials)
                {
                    Assimp.Material aiMaterial = new Assimp.Material();
                    aiMaterial.AddProperty(new Assimp.MaterialProperty(Assimp.Unmanaged.AiMatKeys.NAME, "Material" + (materialIdx++).ToString("00")));

                    if (mat.IsTextured)
                    {
                        aiMaterial.AddProperty(new Assimp.MaterialProperty(Assimp.Unmanaged.AiMatKeys.TEXTURE_BASE, mat.TextureReference.ReferencedTextureName + ".png", Assimp.TextureType.Diffuse, 0));
                    }

                    aiScene.Materials.Add(aiMaterial);
                }

                drawCallIdx++;
            }

            // store node lookup
            Dictionary<RWSceneNode, Assimp.Node> nodeLookup = new Dictionary<RWSceneNode, Assimp.Node>();

            // first create the root node
            var rootNode = new Assimp.Node("SceneRoot");
            rootNode.Transform = scene.Nodes[0].Transform.ToAssimpMatrix4x4();
            nodeLookup.Add(scene.Nodes[0], rootNode);

            for (int i = 1; i < scene.Nodes.Count - 1; i++)
            {
                var node = scene.Nodes[i];
                string name = node.BoneMetadata.BoneNameID.ToString();

                var aiNode = new Assimp.Node(name);
                aiNode.Transform = node.Transform.ToAssimpMatrix4x4();

                // get the associated meshes for this node
                var drawCalls = scene.DrawCalls.FindAll(dc => dc.NodeIndex == i);
                foreach (var drawCall in drawCalls)
                {
                    for (int j = 0; j < scene.Meshes[drawCall.MeshIndex].MaterialCount; j++)
                    {
                        aiNode.MeshIndices.Add(meshStartIndices[scene.DrawCalls.IndexOf(drawCall)] + j);
                    }
                }

                nodeLookup[node.Parent].Children.Add(aiNode);
                nodeLookup.Add(node, aiNode);
            }

            aiScene.RootNode = rootNode;

            return aiScene;
        }