From 33f2c5fbf72daa4de698861ec8329737f87cf33c Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Wed, 11 Sep 2024 18:08:48 +0800 Subject: [PATCH] add normals to CustomGeometry implementation --- thermion_dart/native/src/CustomGeometry.cpp | 95 ++++++++++++++++++++- 1 file changed, 91 insertions(+), 4 deletions(-) diff --git a/thermion_dart/native/src/CustomGeometry.cpp b/thermion_dart/native/src/CustomGeometry.cpp index a8799de5..48d7aa91 100644 --- a/thermion_dart/native/src/CustomGeometry.cpp +++ b/thermion_dart/native/src/CustomGeometry.cpp @@ -1,10 +1,16 @@ +#include + +#include "math.h" + #include #include #include #include #include #include +#include +#include "Log.hpp" #include "CustomGeometry.hpp" namespace thermion_filament { @@ -14,6 +20,8 @@ using namespace filament; CustomGeometry::CustomGeometry( float* vertices, uint32_t numVertices, + float* normals, + uint32_t numNormals, uint16_t* indices, uint32_t numIndices, RenderableManager::PrimitiveType primitiveType, @@ -23,13 +31,19 @@ CustomGeometry::CustomGeometry( this->vertices = new float[numVertices]; std::memcpy(this->vertices, vertices, numVertices * sizeof(float)); + if(numNormals > 0) { + Log("numNormals %d", numNormals); + this->normals = new float[numNormals]; + std::memcpy(this->normals, normals, numNormals * sizeof(float)); + } + this->indices = new uint16_t[numIndices]; std::memcpy(this->indices, indices, numIndices * sizeof(uint16_t)); computeBoundingBox(); } -IndexBuffer* CustomGeometry::indexBuffer() { +IndexBuffer* CustomGeometry::indexBuffer() const { IndexBuffer::BufferDescriptor::Callback indexCallback = [](void *buf, size_t, void *data) { @@ -46,21 +60,94 @@ IndexBuffer* CustomGeometry::indexBuffer() { return indexBuffer; } -VertexBuffer* CustomGeometry::vertexBuffer() { +VertexBuffer* CustomGeometry::vertexBuffer() const { VertexBuffer::BufferDescriptor::Callback vertexCallback = [](void *buf, size_t, void *data) { // free((void *)buf); }; - auto vertexBuffer = VertexBuffer::Builder() + std::vector triangles; + for(int i=0; i < numIndices; i+=3) { + filament::math::ushort3 triangle; + triangle.x = this->indices[i]; + triangle.y = this->indices[i+1]; + triangle.z = this->indices[i+2]; + triangles.push_back(triangle); + } + + + // Create a SurfaceOrientation builder + geometry::SurfaceOrientation::Builder builder; + builder.vertexCount(numVertices) + .normals((filament::math::float3*)normals) + .positions((filament::math::float3*)this->vertices) + .triangleCount(triangles.size()) + .triangles(triangles.data()); + + // Build the SurfaceOrientation object + auto orientation = builder.build(); + + // Retrieve the quaternions + auto quats = new std::vector(numVertices); + orientation->getQuats(quats->data(), numVertices); + + // Create dummy UV data + auto dummyUVs = new std::vector(numVertices, filament::math::float2{0.0f, 0.0f}); + + // Create dummy vertex color data (white color for all vertices) + auto dummyColors = new std::vector(numVertices, filament::math::float4{1.0f, 1.0f, 1.0f, 1.0f}); + + auto vertexBufferBuilder = VertexBuffer::Builder() .vertexCount(numVertices) - .bufferCount(1) .attribute(VertexAttribute::POSITION, 0, VertexBuffer::AttributeType::FLOAT3) + .attribute(VertexAttribute::UV0, 1, VertexBuffer::AttributeType::FLOAT2) + .attribute(VertexAttribute::UV1, 2, VertexBuffer::AttributeType::FLOAT2) + .attribute(VertexAttribute::COLOR, 3, VertexBuffer::AttributeType::FLOAT4); + + if(this->normals) { + vertexBufferBuilder + .bufferCount(5) + .attribute(VertexAttribute::TANGENTS, 4, filament::VertexBuffer::AttributeType::FLOAT4); + } else { + vertexBufferBuilder = vertexBufferBuilder.bufferCount(4); + } + auto vertexBuffer = vertexBufferBuilder .build(*_engine); vertexBuffer->setBufferAt(*_engine, 0, VertexBuffer::BufferDescriptor( this->vertices, vertexBuffer->getVertexCount() * sizeof(math::float3), vertexCallback)); + + + // Set UV0 buffer + vertexBuffer->setBufferAt(*_engine, 1, VertexBuffer::BufferDescriptor( + dummyUVs->data(), dummyUVs->size() * sizeof(math::float2), + [](void* buf, size_t, void* data) { + delete static_cast*>(data); + }, dummyUVs)); + + // Set UV1 buffer + vertexBuffer->setBufferAt(*_engine, 2, VertexBuffer::BufferDescriptor( + dummyUVs->data(), dummyUVs->size() * sizeof(math::float2), + [](void* buf, size_t, void* data) { + // Do nothing here, as we're reusing the same data as UV0 + }, nullptr)); + + // Set vertex color buffer + vertexBuffer->setBufferAt(*_engine, 3, VertexBuffer::BufferDescriptor( + dummyColors->data(), dummyColors->size() * sizeof(math::float4), + [](void* buf, size_t, void* data) { + delete static_cast*>(data); + }, dummyColors)); + + if(this->normals) { + vertexBuffer->setBufferAt(*_engine, 4, VertexBuffer::BufferDescriptor( + quats->data(), quats->size() * sizeof(math::quatf), [] (void *buf, size_t, + void *data) + { + delete (std::vector*)data; + }, (void*)quats)); + } return vertexBuffer; }