public static ResourceSet GenerateTextureResourceSetForCubeMapping <T>(ModelRuntimeDescriptor <T> modelRuntimeState, int meshIndex, DisposeCollectorResourceFactory factory, GraphicsDevice graphicsDevice) where T : struct, VertexLocateable { RealtimeMaterial material = modelRuntimeState.Model.GetMaterial(meshIndex); Image <Rgba32> front = Image.Load <Rgba32>(Path.Combine(AppContext.BaseDirectory, modelRuntimeState.Model.BaseDir, material.cubeMapFront)); Image <Rgba32> back = Image.Load <Rgba32>(Path.Combine(AppContext.BaseDirectory, modelRuntimeState.Model.BaseDir, material.cubeMapBack)); Image <Rgba32> left = Image.Load <Rgba32>(Path.Combine(AppContext.BaseDirectory, modelRuntimeState.Model.BaseDir, material.cubeMapLeft)); Image <Rgba32> right = Image.Load <Rgba32>(Path.Combine(AppContext.BaseDirectory, modelRuntimeState.Model.BaseDir, material.cubeMapRight)); Image <Rgba32> top = Image.Load <Rgba32>(Path.Combine(AppContext.BaseDirectory, modelRuntimeState.Model.BaseDir, material.cubeMapTop)); Image <Rgba32> bottom = Image.Load <Rgba32>(Path.Combine(AppContext.BaseDirectory, modelRuntimeState.Model.BaseDir, material.cubeMapBottom)); TextureView cubeMapTextureView = ResourceGenerator.CreateCubeMapTextureViewFromImages(front, back, left, right, top, bottom, factory, graphicsDevice); return(factory.CreateResourceSet(new ResourceSetDescription( modelRuntimeState.TextureResourceLayout, cubeMapTextureView, modelRuntimeState.TextureSampler ))); }
public static ResourceSet GenerateTextureResourceSetForDiffuseMapping <T>(ModelRuntimeDescriptor <T> modelRuntimeState, int meshIndex, DisposeCollectorResourceFactory factory, GraphicsDevice graphicsDevice) where T : struct, VertexLocateable { RealtimeMaterial material = modelRuntimeState.Model.GetMaterial(meshIndex); ImageSharpTexture diffuseTextureIS = new ImageSharpTexture(Path.Combine(AppContext.BaseDirectory, modelRuntimeState.Model.BaseDir, material.textureDiffuse)); Texture diffuseTexture = diffuseTextureIS.CreateDeviceTexture(graphicsDevice, factory); TextureView diffuseTextureView = factory.CreateTextureView(diffuseTexture); return(factory.CreateResourceSet(new ResourceSetDescription( modelRuntimeState.TextureResourceLayout, diffuseTextureView, modelRuntimeState.TextureSampler ))); }
/// <summary> /// Render Commands for Mesh of Type: /// <see cref="Henzai.Geometry.VertexPositionNormalTextureTangentBitangent"/> ///</summary> private static void GenerateCommandsForPNTTB_Inline( CommandList commandList, ModelRuntimeDescriptor <VertexPositionNormalTextureTangentBitangent> modelState, int meshIndex, SceneRuntimeDescriptor sceneRuntimeDescriptor, ResourceSet[] effectResourceSets, RealtimeMaterial material, Mesh <VertexPositionNormalTextureTangentBitangent> mesh, uint modelInstanceCount) { var effectIndex = 5; var vertexBuffer = modelState.VertexBuffers[meshIndex]; var indexBuffer = modelState.IndexBuffers[meshIndex]; var textureResourceSet = modelState.TextureResourceSets[meshIndex]; var cameraProjViewBuffer = sceneRuntimeDescriptor.CameraProjViewBuffer; var materialBuffer = sceneRuntimeDescriptor.MaterialBuffer; var cameraResourceSet = sceneRuntimeDescriptor.CameraResourceSet; var lightResourceSet = sceneRuntimeDescriptor.LightResourceSet; var pointlightResourceSet = sceneRuntimeDescriptor.SpotLightResourceSet; var materialResourceSet = sceneRuntimeDescriptor.MaterialResourceSet; commandList.SetVertexBuffer(0, vertexBuffer); commandList.SetIndexBuffer(indexBuffer, IndexFormat.UInt16); commandList.UpdateBuffer(cameraProjViewBuffer, 128, mesh.World); commandList.SetGraphicsResourceSet(0, cameraResourceSet); // Always after SetPipeline commandList.SetGraphicsResourceSet(1, lightResourceSet); commandList.SetGraphicsResourceSet(2, pointlightResourceSet); commandList.UpdateBuffer(materialBuffer, 0, material.diffuse); commandList.UpdateBuffer(materialBuffer, 16, material.specular); commandList.UpdateBuffer(materialBuffer, 32, material.ambient); commandList.UpdateBuffer(materialBuffer, 48, material.coefficients); commandList.SetGraphicsResourceSet(3, materialResourceSet); commandList.SetGraphicsResourceSet(4, textureResourceSet); for (int i = 0; i < effectResourceSets.Length; i++) { var resourceSet = effectResourceSets[i]; var resourceSetIndex = effectIndex + i; commandList.SetGraphicsResourceSet((uint)resourceSetIndex, resourceSet); } commandList.DrawIndexed( indexCount: mesh.Indices.Length.ToUnsigned(), instanceCount: modelInstanceCount, indexStart: 0, vertexOffset: 0, instanceStart: 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); }
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)); }