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); }
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)); }