| 317 | } |
| 318 | |
| 319 | void MeshAccelerationStructure::Add(Model* model, int32 lodIndex) |
| 320 | { |
| 321 | PROFILE_CPU(); |
| 322 | lodIndex = Math::Clamp(lodIndex, model->HighestResidentLODIndex(), model->LODs.Count() - 1); |
| 323 | ModelLOD& lod = model->LODs[lodIndex]; |
| 324 | _meshes.EnsureCapacity(_meshes.Count() + lod.Meshes.Count()); |
| 325 | for (int32 i = 0; i < lod.Meshes.Count(); i++) |
| 326 | { |
| 327 | auto& mesh = lod.Meshes[i]; |
| 328 | const MaterialSlot& materialSlot = model->MaterialSlots[mesh.GetMaterialSlotIndex()]; |
| 329 | if (materialSlot.Material && !materialSlot.Material->WaitForLoaded()) |
| 330 | { |
| 331 | // Skip transparent materials |
| 332 | if (materialSlot.Material->GetInfo().BlendMode != MaterialBlendMode::Opaque) |
| 333 | continue; |
| 334 | } |
| 335 | |
| 336 | auto& meshData = _meshes.AddOne(); |
| 337 | meshData.Asset = model; |
| 338 | model->AddReference(); |
| 339 | MeshAccessor accessor; |
| 340 | MeshBufferType bufferTypes[2] = { MeshBufferType::Index, MeshBufferType::Vertex0 }; |
| 341 | if (accessor.LoadMesh(&mesh, false, ToSpan(bufferTypes, 2))) |
| 342 | return; |
| 343 | auto indexStream = accessor.Index(); |
| 344 | auto positionStream = accessor.Position(); |
| 345 | if (!indexStream.IsValid() || !positionStream.IsValid()) |
| 346 | return; |
| 347 | meshData.Indices = indexStream.GetCount(); |
| 348 | meshData.Vertices = positionStream.GetCount(); |
| 349 | meshData.IndexBuffer.Copy(indexStream.GetData()); |
| 350 | meshData.VertexBuffer.Allocate(meshData.Vertices * sizeof(Float3)); |
| 351 | positionStream.CopyTo(ToSpan(meshData.VertexBuffer.Get<Float3>(), meshData.Vertices)); |
| 352 | meshData.Use16BitIndexBuffer = indexStream.GetFormat() == PixelFormat::R16_UInt; |
| 353 | meshData.Bounds = mesh.GetBox(); |
| 354 | } |
| 355 | } |
| 356 | |
| 357 | void MeshAccelerationStructure::Add(const ModelData* modelData, int32 lodIndex, bool copy) |
| 358 | { |
no test coverage detected