Exemple #1
0
        public static LoadedModels <RealtimeMaterial> LoadRealtimeModelsFromFile(string baseDirectory, string localPath, PostProcessSteps flags = DefaultPostProcessSteps)
        {
            string filePath = Path.Combine(baseDirectory, localPath);

            string[] directoryStructure = localPath.Split('/');
            string   modelDir           = directoryStructure[0];

            AssimpContext assimpContext = new AssimpContext();

            Assimp.Scene pScene = assimpContext.ImportFile(filePath, flags);

            //TODO: Identify meshcount for each vertex type. Have to preprocess
            int meshCount = pScene.MeshCount;

            var loadedMeshCounts = pScene.GetHenzaiMeshCounts();
            int meshCountP       = loadedMeshCounts.meshCountP;
            int meshCountPC      = loadedMeshCounts.meshCountPC;
            int meshCountPN      = loadedMeshCounts.meshCountPN;
            int meshCountPT      = loadedMeshCounts.meshCountPT;
            int meshCountPNT     = loadedMeshCounts.meshCountPNT;
            int meshCountPNTTB   = loadedMeshCounts.meshCountPNTTB;

            Mesh <VertexPosition>[]              meshesP   = new Mesh <VertexPosition> [meshCountP];
            Mesh <VertexPositionColor>[]         meshesPC  = new Mesh <VertexPositionColor> [meshCountPC];
            Mesh <VertexPositionNormal>[]        meshesPN  = new Mesh <VertexPositionNormal> [meshCountPN];
            Mesh <VertexPositionTexture>[]       meshesPT  = new Mesh <VertexPositionTexture> [meshCountPT];
            Mesh <VertexPositionNormalTexture>[] meshesPNT = new Mesh <VertexPositionNormalTexture> [meshCountPNT];
            Mesh <VertexPositionNormalTextureTangentBitangent>[] meshesPNTTB = new Mesh <VertexPositionNormalTextureTangentBitangent> [meshCountPNTTB];

            RealtimeMaterial[] materialsP     = new RealtimeMaterial[meshCountP];
            RealtimeMaterial[] materialsPC    = new RealtimeMaterial[meshCountPC];
            RealtimeMaterial[] materialsPN    = new RealtimeMaterial[meshCountPN];
            RealtimeMaterial[] materialsPT    = new RealtimeMaterial[meshCountPT];
            RealtimeMaterial[] materialsPNT   = new RealtimeMaterial[meshCountPNT];
            RealtimeMaterial[] materialsPNTTB = new RealtimeMaterial[meshCountPNTTB];

            ushort[][] meshIndiciesP     = new ushort[meshCountP][];
            ushort[][] meshIndiciesPC    = new ushort[meshCountPC][];
            ushort[][] meshIndiciesPN    = new ushort[meshCountPN][];
            ushort[][] meshIndiciesPT    = new ushort[meshCountPT][];
            ushort[][] meshIndiciesPNT   = new ushort[meshCountPNT][];
            ushort[][] meshIndiciesPNTTB = new ushort[meshCountPNTTB][];

            int meshIndiciesP_Counter     = 0;
            int meshIndiciesPC_Counter    = 0;
            int meshIndiciesPN_Counter    = 0;
            int meshIndiciesPT_Counter    = 0;
            int meshIndiciesPNT_Counter   = 0;
            int meshIndiciesPNTTB_Counter = 0;

            var loadedModels = new LoadedModels <RealtimeMaterial>();

            VertexPosition[]              meshDefinitionP   = new VertexPosition[0];
            VertexPositionColor[]         meshDefinitionPC  = new VertexPositionColor[0];
            VertexPositionNormal[]        meshDefinitionPN  = new VertexPositionNormal[0];
            VertexPositionTexture[]       meshDefinitionPT  = new VertexPositionTexture[0];
            VertexPositionNormalTexture[] meshDefinitionPNT = new VertexPositionNormalTexture[0];
            VertexPositionNormalTextureTangentBitangent[] meshDefinitionPNTTB = new VertexPositionNormalTextureTangentBitangent[0];

            for (int i = 0; i < meshCount; i++)
            {
                var aiMesh      = pScene.Meshes[i];
                var vertexCount = aiMesh.VertexCount;
                if (vertexCount == 0)
                {
                    Console.Error.WriteLine("Mesh has no verticies");
                    continue;
                }

                Assimp.Material aiMaterial = pScene.Materials[aiMesh.MaterialIndex];
                Core.Materials.RealtimeMaterial material = aiMaterial.ToRealtimeMaterial();
                VertexRuntimeTypes henzaiVertexType      = aiMaterial.ToHenzaiVertexType();
                switch (henzaiVertexType)
                {
                case VertexRuntimeTypes.VertexPosition:
                    meshDefinitionP = new VertexPosition[vertexCount];
                    break;

                case VertexRuntimeTypes.VertexPositionColor:
                    meshDefinitionPC = new VertexPositionColor[vertexCount];
                    break;

                case VertexRuntimeTypes.VertexPositionTexture:
                    meshDefinitionPT = new VertexPositionTexture[vertexCount];
                    break;

                case VertexRuntimeTypes.VertexPositionNormalTexture:
                    meshDefinitionPNT = new VertexPositionNormalTexture[vertexCount];
                    break;

                case VertexRuntimeTypes.VertexPositionNormal:
                    meshDefinitionPN = new VertexPositionNormal[vertexCount];
                    break;

                case VertexRuntimeTypes.VertexPositionNormalTextureTangentBitangent:
                    meshDefinitionPNTTB = new VertexPositionNormalTextureTangentBitangent[vertexCount];
                    break;

                default:
                    throw new NotImplementedException($"{henzaiVertexType.ToString("g")} not implemented");
                }

                for (int j = 0; j < vertexCount; j++)
                {
                    byte[] bytes = GenerateVertexBytesArrayFromAssimp(henzaiVertexType, aiMesh, j);

                    switch (henzaiVertexType)
                    {
                    case VertexRuntimeTypes.VertexPosition:
                        meshDefinitionP[j] = ByteMarshal.ByteArrayToStructure <VertexPosition>(bytes);
                        break;

                    case VertexRuntimeTypes.VertexPositionColor:
                        meshDefinitionPC[j] = ByteMarshal.ByteArrayToStructure <VertexPositionColor>(bytes);
                        break;

                    case VertexRuntimeTypes.VertexPositionTexture:
                        meshDefinitionPT[j] = ByteMarshal.ByteArrayToStructure <VertexPositionTexture>(bytes);
                        break;

                    case VertexRuntimeTypes.VertexPositionNormalTexture:
                        meshDefinitionPNT[j] = ByteMarshal.ByteArrayToStructure <VertexPositionNormalTexture>(bytes);
                        break;

                    case VertexRuntimeTypes.VertexPositionNormal:
                        meshDefinitionPN[j] = ByteMarshal.ByteArrayToStructure <VertexPositionNormal>(bytes);
                        break;

                    case VertexRuntimeTypes.VertexPositionNormalTextureTangentBitangent:
                        meshDefinitionPNTTB[j] = ByteMarshal.ByteArrayToStructure <VertexPositionNormalTextureTangentBitangent>(bytes);
                        break;

                    default:
                        throw new NotImplementedException($"{henzaiVertexType.ToString("g")} not implemented");
                    }
                }

                var faceCount = aiMesh.FaceCount;
                switch (henzaiVertexType)
                {
                case VertexRuntimeTypes.VertexPosition:
                    materialsP[meshIndiciesP_Counter]    = material;
                    meshIndiciesP[meshIndiciesP_Counter] = new ushort[3 * faceCount];

                    for (int j = 0; j < faceCount; j++)
                    {
                        var face = aiMesh.Faces[j];

                        if (face.IndexCount != 3)
                        {
                            Console.Error.WriteLine("Loading Assimp: Face index count != 3!");
                            continue;
                        }

                        meshIndiciesP[meshIndiciesP_Counter][3 * j + 0] = face.Indices[0].ToUnsignedShort();
                        meshIndiciesP[meshIndiciesP_Counter][3 * j + 1] = face.Indices[1].ToUnsignedShort();
                        meshIndiciesP[meshIndiciesP_Counter][3 * j + 2] = face.Indices[2].ToUnsignedShort();
                    }
                    meshesP[meshIndiciesP_Counter] = new Mesh <VertexPosition>(meshDefinitionP, meshIndiciesP[meshIndiciesP_Counter]);
                    meshIndiciesP_Counter++;
                    break;

                case VertexRuntimeTypes.VertexPositionColor:
                    materialsPC[meshIndiciesPC_Counter]    = material;
                    meshIndiciesPC[meshIndiciesPC_Counter] = new ushort[3 * faceCount];

                    for (int j = 0; j < faceCount; j++)
                    {
                        var face = aiMesh.Faces[j];

                        if (face.IndexCount != 3)
                        {
                            Console.Error.WriteLine("Loading Assimp: Face index count != 3!");
                            continue;
                        }

                        meshIndiciesPC[meshIndiciesPC_Counter][3 * j + 0] = face.Indices[0].ToUnsignedShort();
                        meshIndiciesPC[meshIndiciesPC_Counter][3 * j + 1] = face.Indices[1].ToUnsignedShort();
                        meshIndiciesPC[meshIndiciesPC_Counter][3 * j + 2] = face.Indices[2].ToUnsignedShort();
                    }
                    meshesPC[meshIndiciesPC_Counter] = new Mesh <VertexPositionColor>(meshDefinitionPC, meshIndiciesPC[meshIndiciesPC_Counter]);
                    meshIndiciesPC_Counter++;
                    break;

                case VertexRuntimeTypes.VertexPositionTexture:
                    materialsPT[meshIndiciesPT_Counter]    = material;
                    meshIndiciesPT[meshIndiciesPT_Counter] = new ushort[3 * faceCount];

                    for (int j = 0; j < faceCount; j++)
                    {
                        var face = aiMesh.Faces[j];

                        if (face.IndexCount != 3)
                        {
                            Console.Error.WriteLine("Loading Assimp: Face index count != 3!");
                            continue;
                        }

                        meshIndiciesPT[meshIndiciesPT_Counter][3 * j + 0] = face.Indices[0].ToUnsignedShort();
                        meshIndiciesPT[meshIndiciesPT_Counter][3 * j + 1] = face.Indices[1].ToUnsignedShort();
                        meshIndiciesPT[meshIndiciesPT_Counter][3 * j + 2] = face.Indices[2].ToUnsignedShort();
                    }
                    meshesPT[meshIndiciesPT_Counter] = new Mesh <VertexPositionTexture>(meshDefinitionPT, meshIndiciesPT[meshIndiciesPT_Counter]);
                    meshIndiciesPT_Counter++;
                    break;

                case VertexRuntimeTypes.VertexPositionNormalTexture:
                    materialsPNT[meshIndiciesPNT_Counter]    = material;
                    meshIndiciesPNT[meshIndiciesPNT_Counter] = new ushort[3 * faceCount];

                    for (int j = 0; j < faceCount; j++)
                    {
                        var face = aiMesh.Faces[j];

                        if (face.IndexCount != 3)
                        {
                            Console.Error.WriteLine("Loading Assimp: Face index count != 3!");
                            continue;
                        }

                        meshIndiciesPNT[meshIndiciesPNT_Counter][3 * j + 0] = face.Indices[0].ToUnsignedShort();
                        meshIndiciesPNT[meshIndiciesPNT_Counter][3 * j + 1] = face.Indices[1].ToUnsignedShort();
                        meshIndiciesPNT[meshIndiciesPNT_Counter][3 * j + 2] = face.Indices[2].ToUnsignedShort();
                    }
                    meshesPNT[meshIndiciesPNT_Counter] = new Mesh <VertexPositionNormalTexture>(meshDefinitionPNT, meshIndiciesPNT[meshIndiciesPNT_Counter]);
                    meshIndiciesPNT_Counter++;
                    break;

                case VertexRuntimeTypes.VertexPositionNormal:
                    materialsPN[meshIndiciesPN_Counter]    = material;
                    meshIndiciesPN[meshIndiciesPN_Counter] = new ushort[3 * faceCount];

                    for (int j = 0; j < faceCount; j++)
                    {
                        var face = aiMesh.Faces[j];

                        if (face.IndexCount != 3)
                        {
                            Console.Error.WriteLine("Loading Assimp: Face index count != 3!");
                            continue;
                        }

                        meshIndiciesPN[meshIndiciesPN_Counter][3 * j + 0] = face.Indices[0].ToUnsignedShort();
                        meshIndiciesPN[meshIndiciesPN_Counter][3 * j + 1] = face.Indices[1].ToUnsignedShort();
                        meshIndiciesPN[meshIndiciesPN_Counter][3 * j + 2] = face.Indices[2].ToUnsignedShort();
                    }
                    meshesPN[meshIndiciesPN_Counter] = new Mesh <VertexPositionNormal>(meshDefinitionPN, meshIndiciesPN[meshIndiciesPN_Counter]);
                    meshIndiciesPN_Counter++;
                    break;

                case VertexRuntimeTypes.VertexPositionNormalTextureTangentBitangent:
                    materialsPNTTB[meshIndiciesPNTTB_Counter]    = material;
                    meshIndiciesPNTTB[meshIndiciesPNTTB_Counter] = new ushort[3 * faceCount];

                    for (int j = 0; j < faceCount; j++)
                    {
                        var face = aiMesh.Faces[j];

                        if (face.IndexCount != 3)
                        {
                            Console.Error.WriteLine("Loading Assimp: Face index count != 3!");
                            continue;
                        }

                        meshIndiciesPNTTB[meshIndiciesPNTTB_Counter][3 * j + 0] = face.Indices[0].ToUnsignedShort();
                        meshIndiciesPNTTB[meshIndiciesPNTTB_Counter][3 * j + 1] = face.Indices[1].ToUnsignedShort();
                        meshIndiciesPNTTB[meshIndiciesPNTTB_Counter][3 * j + 2] = face.Indices[2].ToUnsignedShort();
                    }
                    meshesPNTTB[meshIndiciesPNTTB_Counter] = new Mesh <VertexPositionNormalTextureTangentBitangent>(meshDefinitionPNTTB, meshIndiciesPNTTB[meshIndiciesPNTTB_Counter]);
                    meshIndiciesPNTTB_Counter++;
                    break;

                default:
                    throw new NotImplementedException($"{henzaiVertexType.ToString("g")} not implemented");
                }
            }

            if (meshCountP > 0)
            {
                loadedModels.modelP = new Model <VertexPosition, RealtimeMaterial>(modelDir, meshesP, materialsP);
            }
            if (meshCountPC > 0)
            {
                loadedModels.modelPC = new Model <VertexPositionColor, RealtimeMaterial>(modelDir, meshesPC, materialsPC);
            }
            if (meshCountPN > 0)
            {
                loadedModels.modelPN = new Model <VertexPositionNormal, RealtimeMaterial>(modelDir, meshesPN, materialsPN);
            }
            if (meshCountPT > 0)
            {
                loadedModels.modelPT = new Model <VertexPositionTexture, RealtimeMaterial>(modelDir, meshesPT, materialsPT);
            }
            if (meshCountPNT > 0)
            {
                loadedModels.modelPNT = new Model <VertexPositionNormalTexture, RealtimeMaterial>(modelDir, meshesPNT, materialsPNT);
            }
            if (meshCountPNTTB > 0)
            {
                loadedModels.modelPNTTB = new Model <VertexPositionNormalTextureTangentBitangent, RealtimeMaterial>(modelDir, meshesPNTTB, materialsPNTTB);
            }

            return(loadedModels);
        }
Exemple #2
0
        public static Model <T, RealtimeMaterial> LoadFromFileWithRealtimeMaterial <T>(string baseDirectory, string localPath, VertexRuntimeTypes vertexType, PostProcessSteps flags = DefaultPostProcessSteps) where T : struct, VertexLocateable
        {
            if (!Verifier.VerifyVertexStruct <T>(vertexType))
            {
                throw new ArgumentException($"Vertex Type Mismatch AssimpLoader");
            }

            string filePath = Path.Combine(baseDirectory, localPath);

            string[] directoryStructure = localPath.Split('/');
            string   modelDir           = directoryStructure[0];

            AssimpContext assimpContext = new AssimpContext();

            Assimp.Scene pScene = assimpContext.ImportFile(filePath, flags);

            int meshCount = pScene.MeshCount;

            Mesh <T>[]         meshes       = new Mesh <T> [meshCount];
            RealtimeMaterial[] materials    = new RealtimeMaterial[meshCount];
            ushort[][]         meshIndicies = new ushort[meshCount][];

            for (int i = 0; i < meshCount; i++)
            {
                var aiMesh      = pScene.Meshes[i];
                var vertexCount = aiMesh.VertexCount;
                if (vertexCount == 0)
                {
                    continue;
                }

                Assimp.Material aiMaterial = pScene.Materials[aiMesh.MaterialIndex];
                var             material   = aiMaterial.ToRealtimeMaterial();

                T[] meshDefinition = new T[vertexCount];

                for (int j = 0; j < vertexCount; j++)
                {
                    byte[] bytes = GenerateVertexBytesArrayFromAssimp(vertexType, aiMesh, j);
                    meshDefinition[j] = ByteMarshal.ByteArrayToStructure <T>(bytes);
                }

                materials[i] = material;
                var faceCount = aiMesh.FaceCount;
                meshIndicies[i] = new ushort[3 * faceCount];

                for (int j = 0; j < faceCount; j++)
                {
                    var face = aiMesh.Faces[j];

                    if (face.IndexCount != 3)
                    {
                        Console.Error.WriteLine("Loading Assimp: Face index count != 3!");
                        continue;
                    }

                    meshIndicies[i][3 * j + 0] = face.Indices[0].ToUnsignedShort();
                    meshIndicies[i][3 * j + 1] = face.Indices[1].ToUnsignedShort();
                    meshIndicies[i][3 * j + 2] = face.Indices[2].ToUnsignedShort();
                }
                meshes[i] = new Mesh <T>(meshDefinition, meshIndicies[i]);
            }

            return(new Model <T, RealtimeMaterial>(modelDir, meshes, materials));
        }