static
| 198 | |
| 199 | // static |
| 200 | Arrow3d::PreloadedData Arrow3d::PreloadMesh(std::optional<Arrow3dCustomDecl> const & customDecl, |
| 201 | ref_ptr<dp::TextureManager> texMng) |
| 202 | { |
| 203 | Arrow3d::PreloadedData data; |
| 204 | |
| 205 | bool const useDefaultResource = !customDecl || customDecl->m_loadFromDefaultResourceFolder; |
| 206 | |
| 207 | // Load arrow mesh. |
| 208 | auto const & meshPath = customDecl ? customDecl->m_arrowMeshPath : kDefaultArrowMesh; |
| 209 | data.m_meshData = PreloadedMeshData{}; |
| 210 | if (!LoadMesh(meshPath, useDefaultResource, |
| 211 | [&](std::vector<float> positions, std::vector<float> normals, std::vector<float> texCoords) |
| 212 | { |
| 213 | if (!positions.empty()) |
| 214 | { |
| 215 | if (normals.empty()) |
| 216 | normals = dp::MeshObject::GenerateNormalsForTriangles(positions, kComponentsInNormal); |
| 217 | |
| 218 | data.m_meshData->m_positions = std::move(positions); |
| 219 | data.m_meshData->m_normals = std::move(normals); |
| 220 | |
| 221 | // Texture coordinates. |
| 222 | ref_ptr<dp::StaticTexture> arrowTexture = texMng->GetArrowTexture(); |
| 223 | CHECK(arrowTexture != nullptr, ("Arrow texture must be initialized before the mesh")); |
| 224 | // NOTE: texture must be loaded before the mesh. |
| 225 | if (arrowTexture->IsLoadingCorrect() && !texCoords.empty()) |
| 226 | { |
| 227 | data.m_arrowMeshTexturingEnabled = true; |
| 228 | data.m_meshData->m_texCoords = std::move(texCoords); |
| 229 | } |
| 230 | else |
| 231 | { |
| 232 | data.m_arrowMeshTexturingEnabled = false; |
| 233 | } |
| 234 | } |
| 235 | else |
| 236 | { |
| 237 | data.m_meshData.reset(); |
| 238 | } |
| 239 | }, [&](std::string const & reason) |
| 240 | { |
| 241 | data.m_meshData.reset(); |
| 242 | LOG(LERROR, ("Arrow3D mesh was not loaded:", reason)); |
| 243 | })) |
| 244 | { |
| 245 | return {}; |
| 246 | } |
| 247 | |
| 248 | // Load shadow arrow mesh. |
| 249 | auto const & shadowMeshPath = customDecl ? customDecl->m_shadowMeshPath : kDefaultArrowShadowMesh; |
| 250 | if (!shadowMeshPath.empty()) |
| 251 | { |
| 252 | data.m_shadowMeshData = PreloadedMeshData{}; |
| 253 | LoadMesh(shadowMeshPath, useDefaultResource, |
| 254 | [&](std::vector<float> positions, std::vector<float> /* normals */, std::vector<float> texCoords) |
| 255 | { |
| 256 | // NOTE: Shadow mesh must contain texture coordinates. They're used to create soft shadow. |
| 257 | if (!positions.empty() && !texCoords.empty()) |
nothing calls this directly
no test coverage detected