| 42 | } |
| 43 | |
| 44 | const Model* ModelManager::CreateFromFile(std::string_view filename) |
| 45 | { |
| 46 | XID modelID = StringToID(filename); |
| 47 | if (m_Models.count(modelID)) |
| 48 | return &m_Models[modelID]; |
| 49 | |
| 50 | using namespace Assimp; |
| 51 | namespace fs = std::filesystem; |
| 52 | Importer importer; |
| 53 | |
| 54 | auto pAssimpScene = importer.ReadFile(filename.data(), aiProcess_ConvertToLeftHanded | |
| 55 | aiProcess_GenBoundingBoxes | aiProcess_Triangulate | aiProcess_ImproveCacheLocality); |
| 56 | |
| 57 | if (pAssimpScene && !(pAssimpScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE) && pAssimpScene->HasMeshes()) |
| 58 | { |
| 59 | auto& model = m_Models[modelID]; |
| 60 | |
| 61 | model.meshdatas.resize(pAssimpScene->mNumMeshes); |
| 62 | model.materials.resize(pAssimpScene->mNumMaterials); |
| 63 | for (uint32_t i = 0; i < pAssimpScene->mNumMeshes; ++i) |
| 64 | { |
| 65 | auto& mesh = model.meshdatas[i]; |
| 66 | |
| 67 | auto pAiMesh = pAssimpScene->mMeshes[i]; |
| 68 | uint32_t numVertices = pAiMesh->mNumVertices; |
| 69 | |
| 70 | CD3D11_BUFFER_DESC bufferDesc(0, D3D11_BIND_VERTEX_BUFFER); |
| 71 | D3D11_SUBRESOURCE_DATA initData{ nullptr, 0, 0 }; |
| 72 | // 位置 |
| 73 | if (pAiMesh->mNumVertices > 0) |
| 74 | { |
| 75 | initData.pSysMem = pAiMesh->mVertices; |
| 76 | bufferDesc.ByteWidth = numVertices * sizeof(XMFLOAT3); |
| 77 | m_pDevice->CreateBuffer(&bufferDesc, &initData, mesh.m_pVertices.GetAddressOf()); |
| 78 | |
| 79 | BoundingBox::CreateFromPoints(mesh.m_BoundingBox, numVertices, |
| 80 | (const XMFLOAT3*)pAiMesh->mVertices, sizeof(XMFLOAT3)); |
| 81 | if (i == 0) |
| 82 | model.boundingbox = mesh.m_BoundingBox; |
| 83 | else |
| 84 | model.boundingbox.CreateMerged(model.boundingbox, model.boundingbox, mesh.m_BoundingBox); |
| 85 | } |
| 86 | |
| 87 | // 法线 |
| 88 | if (pAiMesh->HasNormals()) |
| 89 | { |
| 90 | initData.pSysMem = pAiMesh->mNormals; |
| 91 | bufferDesc.ByteWidth = numVertices * sizeof(XMFLOAT3); |
| 92 | m_pDevice->CreateBuffer(&bufferDesc, &initData, mesh.m_pNormals.GetAddressOf()); |
| 93 | } |
| 94 | |
| 95 | // 切线 |
| 96 | if (pAiMesh->HasTangentsAndBitangents()) |
| 97 | { |
| 98 | std::vector<XMFLOAT4> tangents(numVertices, XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f)); |
| 99 | for (uint32_t i = 0; i < pAiMesh->mNumVertices; ++i) |
| 100 | { |
| 101 | memcpy_s(&tangents[i], sizeof(XMFLOAT3), |
no test coverage detected