| 48 | namespace |
| 49 | { |
| 50 | bool UpdateMesh(MeshBase* mesh, uint32 vertexCount, uint32 triangleCount, PixelFormat indexFormat, const Float3* vertices, const void* triangles, const Float3* normals, const Float3* tangents, const Float2* uvs, const Color32* colors) |
| 51 | { |
| 52 | PROFILE_MEM(GraphicsMeshes); |
| 53 | auto model = mesh->GetModelBase(); |
| 54 | CHECK_RETURN(model && model->IsVirtual(), true); |
| 55 | CHECK_RETURN(triangles && vertices, true); |
| 56 | MeshAccessor accessor; |
| 57 | |
| 58 | // Index Buffer |
| 59 | { |
| 60 | if (accessor.AllocateBuffer(MeshBufferType::Index, triangleCount * 3, indexFormat)) |
| 61 | return true; |
| 62 | auto indexStream = accessor.Index(); |
| 63 | ASSERT(indexStream.IsLinear(indexFormat)); |
| 64 | indexStream.SetLinear(triangles); |
| 65 | } |
| 66 | |
| 67 | // Vertex Buffer 0 (position-only) |
| 68 | { |
| 69 | GPUVertexLayout* vb0layout = GPUVertexLayout::Get({ { VertexElement::Types::Position, 0, 0, 0, PixelFormat::R32G32B32_Float } }); |
| 70 | if (accessor.AllocateBuffer(MeshBufferType::Vertex0, vertexCount, vb0layout)) |
| 71 | return true; |
| 72 | auto positionStream = accessor.Position(); |
| 73 | ASSERT(positionStream.IsLinear(PixelFormat::R32G32B32_Float)); |
| 74 | positionStream.SetLinear(vertices); |
| 75 | } |
| 76 | |
| 77 | // Vertex Buffer 1 (general purpose components) |
| 78 | GPUVertexLayout::Elements vb1elements; |
| 79 | if (normals) |
| 80 | { |
| 81 | vb1elements.Add({ VertexElement::Types::Normal, 1, 0, 0, PixelFormat::R10G10B10A2_UNorm }); |
| 82 | if (tangents) |
| 83 | vb1elements.Add({ VertexElement::Types::Tangent, 1, 0, 0, PixelFormat::R10G10B10A2_UNorm }); |
| 84 | } |
| 85 | if (uvs) |
| 86 | vb1elements.Add({ VertexElement::Types::TexCoord, 1, 0, 0, PixelFormat::R16G16_Float }); |
| 87 | if (vb1elements.HasItems()) |
| 88 | { |
| 89 | GPUVertexLayout* vb1layout = GPUVertexLayout::Get(vb1elements); |
| 90 | if (accessor.AllocateBuffer(MeshBufferType::Vertex1, vertexCount, vb1layout)) |
| 91 | return true; |
| 92 | if (normals) |
| 93 | { |
| 94 | auto normalStream = accessor.Normal(); |
| 95 | if (tangents) |
| 96 | { |
| 97 | auto tangentStream = accessor.Tangent(); |
| 98 | for (uint32 i = 0; i < vertexCount; i++) |
| 99 | { |
| 100 | const Float3 normal = normals[i]; |
| 101 | const Float3 tangent = tangents[i]; |
| 102 | Float3 n; |
| 103 | Float4 t; |
| 104 | RenderTools::CalculateTangentFrame(n, t, normal, tangent); |
| 105 | normalStream.SetFloat3(i, n); |
| 106 | tangentStream.SetFloat4(i, t); |
| 107 | } |