| 703 | } |
| 704 | |
| 705 | bool MeshBase::DownloadDataCPU(MeshBufferType type, BytesContainer& result, int32& count, GPUVertexLayout** layout) const |
| 706 | { |
| 707 | if (_cachedVertexBuffers[0].IsInvalid()) |
| 708 | { |
| 709 | PROFILE_CPU(); |
| 710 | auto model = GetModelBase(); |
| 711 | ScopeLock lock(model->Locker); |
| 712 | if (model->IsVirtual()) |
| 713 | { |
| 714 | LOG(Error, "Cannot access CPU data of virtual models. Use GPU data download."); |
| 715 | return true; |
| 716 | } |
| 717 | |
| 718 | // Fetch chunk with data from drive/memory |
| 719 | const auto chunkIndex = MODEL_LOD_TO_CHUNK_INDEX(GetLODIndex()); |
| 720 | if (model->LoadChunk(chunkIndex)) |
| 721 | return true; |
| 722 | const auto chunk = model->GetChunk(chunkIndex); |
| 723 | if (!chunk) |
| 724 | { |
| 725 | LOG(Error, "Missing chunk."); |
| 726 | return true; |
| 727 | } |
| 728 | MemoryReadStream stream(chunk->Get(), chunk->Size()); |
| 729 | ModelBase::MeshData meshData; |
| 730 | |
| 731 | // Seek to find mesh location |
| 732 | byte meshVersion = stream.ReadByte(); |
| 733 | for (int32 meshIndex = 0; meshIndex <= _index; meshIndex++) |
| 734 | { |
| 735 | if (model->LoadMesh(stream, meshVersion, model->GetMesh(meshIndex, _lodIndex), &meshData)) |
| 736 | return true; |
| 737 | if (meshIndex != _index) |
| 738 | continue; |
| 739 | |
| 740 | // Cache mesh data |
| 741 | _cachedVertexBufferCount = meshData.Vertices; |
| 742 | _cachedIndexBufferCount = (int32)meshData.Triangles * 3; |
| 743 | _cachedIndexBuffer.Copy((const byte*)meshData.IBData, _cachedIndexBufferCount * (int32)meshData.IBStride); |
| 744 | GPUVertexLayout::Elements ibLayout; |
| 745 | ibLayout.Add({ VertexElement::Types::Attribute, 0, 0, 0, meshData.IBStride == sizeof(uint16) ? PixelFormat::R16_UInt : PixelFormat::R32_UInt }); |
| 746 | _cachedVertexLayouts[3] = GPUVertexLayout::Get(ibLayout); |
| 747 | for (int32 vb = 0; vb < meshData.VBData.Count(); vb++) |
| 748 | { |
| 749 | _cachedVertexBuffers[vb].Copy((const byte*)meshData.VBData[vb], (int32)(meshData.VBLayout[vb]->GetStride() * meshData.Vertices)); |
| 750 | _cachedVertexLayouts[vb] = meshData.VBLayout[vb]; |
| 751 | } |
| 752 | break; |
| 753 | } |
| 754 | } |
| 755 | |
| 756 | switch (type) |
| 757 | { |
| 758 | case MeshBufferType::Index: |
| 759 | result.Link(_cachedIndexBuffer); |
| 760 | count = _cachedIndexBufferCount; |
| 761 | if (layout) |
| 762 | *layout = _cachedVertexLayouts[3]; |
no test coverage detected