| 461 | } |
| 462 | |
| 463 | bool ModelBase::SaveLOD(WriteStream& stream, int32 lodIndex) const |
| 464 | { |
| 465 | // Download all meshes buffers from the GPU |
| 466 | Array<Task*> tasks; |
| 467 | Array<const MeshBase*> meshes; |
| 468 | GetMeshes(meshes, lodIndex); |
| 469 | const int32 meshesCount = meshes.Count(); |
| 470 | struct MeshData |
| 471 | { |
| 472 | BytesContainer VB[3]; |
| 473 | BytesContainer IB; |
| 474 | }; |
| 475 | Array<MeshData> meshesData; |
| 476 | meshesData.Resize(meshesCount); |
| 477 | tasks.EnsureCapacity(meshesCount * 4); |
| 478 | for (int32 meshIndex = 0; meshIndex < meshesCount; meshIndex++) |
| 479 | { |
| 480 | const auto& mesh = *meshes[meshIndex]; |
| 481 | auto& meshData = meshesData[meshIndex]; |
| 482 | |
| 483 | // Vertex Buffer 0 (required) |
| 484 | auto task = mesh.DownloadDataGPUAsync(MeshBufferType::Vertex0, meshData.VB[0]); |
| 485 | if (task == nullptr) |
| 486 | return true; |
| 487 | task->Start(); |
| 488 | tasks.Add(task); |
| 489 | |
| 490 | // Vertex Buffer 1 (optional) |
| 491 | task = mesh.DownloadDataGPUAsync(MeshBufferType::Vertex1, meshData.VB[1]); |
| 492 | if (task) |
| 493 | { |
| 494 | task->Start(); |
| 495 | tasks.Add(task); |
| 496 | } |
| 497 | |
| 498 | // Vertex Buffer 2 (optional) |
| 499 | task = mesh.DownloadDataGPUAsync(MeshBufferType::Vertex2, meshData.VB[2]); |
| 500 | if (task) |
| 501 | { |
| 502 | task->Start(); |
| 503 | tasks.Add(task); |
| 504 | } |
| 505 | |
| 506 | // Index Buffer (required) |
| 507 | task = mesh.DownloadDataGPUAsync(MeshBufferType::Index, meshData.IB); |
| 508 | if (task == nullptr) |
| 509 | return true; |
| 510 | task->Start(); |
| 511 | tasks.Add(task); |
| 512 | } |
| 513 | |
| 514 | // Wait for async tasks |
| 515 | if (Task::WaitAll(tasks)) |
| 516 | return true; |
| 517 | |
| 518 | // Create meshes data |
| 519 | static_assert(MODEL_MESH_VERSION == 2, "Update code"); |
| 520 | stream.Write(MODEL_MESH_VERSION); |
nothing calls this directly
no test coverage detected