From 124938dbc2cfeb310b55bf9c576bd8907772887a Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Sat, 2 Nov 2024 10:17:18 +0800 Subject: [PATCH] temporarily disable UnprojectTexture --- .../native/include/CustomGeometry.hpp | 20 +- thermion_dart/native/include/SceneManager.hpp | 14 +- thermion_dart/native/src/CustomGeometry.cpp | 388 ++++++++++-------- thermion_dart/native/src/FilamentViewer.cpp | 10 +- thermion_dart/native/src/HighlightOverlay.cpp | 14 +- thermion_dart/native/src/SceneManager.cpp | 60 ++- thermion_dart/native/src/UnprojectTexture.cpp | 240 +++++------ 7 files changed, 396 insertions(+), 350 deletions(-) diff --git a/thermion_dart/native/include/CustomGeometry.hpp b/thermion_dart/native/include/CustomGeometry.hpp index a3348b43..6f34110f 100644 --- a/thermion_dart/native/include/CustomGeometry.hpp +++ b/thermion_dart/native/include/CustomGeometry.hpp @@ -3,13 +3,16 @@ #include #include +#include #include #include #include #include #include #include -#include + +#include +#include namespace thermion { @@ -32,9 +35,13 @@ public: Engine* engine); ~CustomGeometry(); - VertexBuffer* vertexBuffer() const; - IndexBuffer* indexBuffer() const; - Box getBoundingBox() const; + utils::Entity createInstance(MaterialInstance *materialInstance); + +private: + Engine* _engine; + + VertexBuffer* vertexBuffer; + IndexBuffer* indexBuffer; float* vertices = nullptr; float* normals = nullptr; @@ -45,11 +52,6 @@ public: Box boundingBox; RenderableManager::PrimitiveType primitiveType; -private: - Engine* _engine; - bool _vertexBufferFreed = false; - bool _indexBufferFreed = false; - void computeBoundingBox(); }; diff --git a/thermion_dart/native/include/SceneManager.hpp b/thermion_dart/native/include/SceneManager.hpp index 25f66074..55306160 100644 --- a/thermion_dart/native/include/SceneManager.hpp +++ b/thermion_dart/native/include/SceneManager.hpp @@ -230,7 +230,12 @@ namespace thermion /// @param out a pointer large enough to store four floats (the min/max coordinates of the bounding box) /// @return /// - Aabb2 getBoundingBox(View* view, EntityId entity); + Aabb2 getScreenSpaceBoundingBox(View* view, EntityId entity); + + /// @brief returns the 3D bounding box of the renderable instance for the given entity. + /// @return the bounding box + /// + Aabb3 getRenderableBoundingBox(EntityId entity); /// /// Creates an entity with the specified geometry/material/normals and adds to the scene. @@ -256,11 +261,15 @@ namespace thermion return _unlitMaterialProvider; } + bool isGeometryInstance(EntityId entity) { + return std::find(_geometryInstances.begin(), _geometryInstances.end(), entity) != _geometryInstances.end(); + } + bool isGeometryEntity(EntityId entity) { return _geometry.find(entity) != _geometry.end(); } - const CustomGeometry* const getGeometry(EntityId entityId) { + CustomGeometry* const getGeometry(EntityId entityId) { return _geometry[entityId].get(); } @@ -336,6 +345,7 @@ namespace thermion _instances; tsl::robin_map _assets; tsl::robin_map> _geometry; + std::vector _geometryInstances; tsl::robin_map> _highlighted; tsl::robin_map _transformUpdates; std::set _textures; diff --git a/thermion_dart/native/src/CustomGeometry.cpp b/thermion_dart/native/src/CustomGeometry.cpp index c104866b..c1e49adb 100644 --- a/thermion_dart/native/src/CustomGeometry.cpp +++ b/thermion_dart/native/src/CustomGeometry.cpp @@ -1,4 +1,7 @@ #include "math.h" + +#include + #include #include #include @@ -6,207 +9,232 @@ #include #include #include -#include #include "CustomGeometry.hpp" #include "Log.hpp" +namespace thermion +{ -namespace thermion { + using namespace filament; -using namespace filament; + CustomGeometry::CustomGeometry(float *vertices, uint32_t numVertices, + float *normals, uint32_t numNormals, float *uvs, + uint32_t numUvs, uint16_t *indices, + uint32_t numIndices, + RenderableManager::PrimitiveType primitiveType, + Engine *engine) + : numVertices(numVertices), numIndices(numIndices), _engine(engine) + { -CustomGeometry::CustomGeometry(float *vertices, uint32_t numVertices, - float *normals, uint32_t numNormals, float *uvs, - uint32_t numUvs, uint16_t *indices, - uint32_t numIndices, - RenderableManager::PrimitiveType primitiveType, - Engine *engine) - : numVertices(numVertices), numIndices(numIndices), _engine(engine) { - this->primitiveType = primitiveType; - this->vertices = new float[numVertices]; - std::memcpy(this->vertices, vertices, numVertices * sizeof(float)); + this->primitiveType = primitiveType; + this->vertices = new float[numVertices]; - if (numNormals > 0) { - this->normals = new float[numNormals]; - std::memcpy(this->normals, normals, numNormals * sizeof(float)); - } + std::memcpy(this->vertices, vertices, numVertices * sizeof(float)); - if (numUvs > 0) { - this->uvs = new float[numUvs]; - std::memcpy(this->uvs, uvs, numUvs * sizeof(float)); - } else { - this->uvs = nullptr; - } - - this->indices = new uint16_t[numIndices]; - std::memcpy(this->indices, indices, numIndices * sizeof(uint16_t)); - - computeBoundingBox(); -} - -IndexBuffer *CustomGeometry::indexBuffer() const { - IndexBuffer::BufferDescriptor::Callback indexCallback = [](void *buf, size_t, - void *data) { - // free((void *)buf); - }; - - auto indexBuffer = IndexBuffer::Builder() - .indexCount(numIndices) - .bufferType(IndexBuffer::IndexType::USHORT) - .build(*_engine); - - indexBuffer->setBuffer(*_engine, - IndexBuffer::BufferDescriptor( - this->indices, - indexBuffer->getIndexCount() * sizeof(uint16_t), - indexCallback)); - return indexBuffer; -} - -VertexBuffer *CustomGeometry::vertexBuffer() const { - VertexBuffer::BufferDescriptor::Callback vertexCallback = - [](void *buf, size_t, void *data) { - // free((void *)buf); - }; - - // Use provided UVs or create dummy UV data - std::vector *uvData; - if (this->uvs != nullptr) { - uvData = new std::vector( - (filament::math::float2 *)this->uvs, - (filament::math::float2 *)(this->uvs + numVertices * 2)); - } else { - uvData = 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) - .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( - uvData->data(), uvData->size() * sizeof(math::float2), - [](void *buf, size_t, void *data) { - delete static_cast *>(data); - }, - uvData)); - - // Set UV1 buffer (reusing UV0 data) - vertexBuffer->setBufferAt(*_engine, 2, - VertexBuffer::BufferDescriptor( - uvData->data(), - uvData->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) { - - assert(this->primitiveType == RenderableManager::PrimitiveType::TRIANGLES); - 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); + if (numNormals > 0) + { + this->normals = new float[numNormals]; + std::memcpy(this->normals, normals, numNormals * sizeof(float)); } - // 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()); + if (numUvs > 0) + { + this->uvs = new float[numUvs]; + std::memcpy(this->uvs, uvs, numUvs * sizeof(float)); + } + else + { + this->uvs = nullptr; + } - // Build the SurfaceOrientation object - auto orientation = builder.build(); + this->indices = new uint16_t[numIndices]; - // Retrieve the quaternions - auto quats = new std::vector(numVertices); - orientation->getQuats(quats->data(), numVertices); + std::memcpy(this->indices, indices, numIndices * sizeof(uint16_t)); - vertexBuffer->setBufferAt(*_engine, 4, + computeBoundingBox(); + + indexBuffer = IndexBuffer::Builder() + .indexCount(numIndices) + .bufferType(IndexBuffer::IndexType::USHORT) + .build(*_engine); + + indexBuffer->setBuffer(*_engine, + IndexBuffer::BufferDescriptor( + this->indices, + indexBuffer->getIndexCount() * sizeof(uint16_t), + [](void *buf, size_t, + void *data) + { + free((void *)buf); + })); + + std::vector *uvData; + if (this->uvs != nullptr) + { + uvData = new std::vector( + (filament::math::float2 *)this->uvs, + (filament::math::float2 *)(this->uvs + numVertices * 2)); + } + else + { + uvData = 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) + .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); + } + + vertexBuffer = vertexBufferBuilder.build(*_engine); + + vertexBuffer->setBufferAt( + *_engine, 0, + VertexBuffer::BufferDescriptor( + this->vertices, numVertices * sizeof(math::float3), + [](void *buf, size_t, void *data) + { + free((void *)buf); + })); + + // Set UV0 buffer + vertexBuffer->setBufferAt( + *_engine, 1, + VertexBuffer::BufferDescriptor( + uvData->data(), uvData->size() * sizeof(math::float2), + [](void *buf, size_t, void *data) + { + delete static_cast *>(data); + }, + uvData)); + + // Set UV1 buffer (reusing UV0 data) + vertexBuffer->setBufferAt(*_engine, 2, VertexBuffer::BufferDescriptor( - quats->data(), - quats->size() * sizeof(math::quatf), - [](void *buf, size_t, void *data) { - delete (std::vector *)data; + uvData->data(), + uvData->size() * sizeof(math::float2), + [](void *buf, size_t, void *data) + { + // Do nothing here, as we're reusing the same + // data as UV0 }, - (void *)quats)); - } - return vertexBuffer; -} + nullptr)); -CustomGeometry::~CustomGeometry() { - delete[] vertices; - delete[] indices; - if (normals) - delete[] normals; - if (uvs) - delete[] uvs; -} + // 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)); -void CustomGeometry::computeBoundingBox() { - float minX = FLT_MAX, minY = FLT_MAX, minZ = FLT_MAX; - float maxX = -FLT_MAX, maxY = -FLT_MAX, maxZ = -FLT_MAX; + if (this->normals) + { - for (uint32_t i = 0; i < numVertices; i += 3) { - minX = std::min(vertices[i], minX); - minY = std::min(vertices[i + 1], minY); - minZ = std::min(vertices[i + 2], minZ); - maxX = std::max(vertices[i], maxX); - maxY = std::max(vertices[i + 1], maxY); - maxZ = std::max(vertices[i + 2], maxZ); + assert(this->primitiveType == RenderableManager::PrimitiveType::TRIANGLES); + 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); + + 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)); + } } - boundingBox = Box{{minX, minY, minZ}, {maxX, maxY, maxZ}}; -} + utils::Entity CustomGeometry::createInstance(MaterialInstance *materialInstance) { + auto entity = utils::EntityManager::get().create(); + RenderableManager::Builder builder(1); -Box CustomGeometry::getBoundingBox() const { return boundingBox; } + builder.boundingBox(boundingBox) + .geometry(0, primitiveType, vertexBuffer, indexBuffer, 0, numIndices) + .culling(true) + .receiveShadows(true) + .castShadows(true); + + builder.material(0, materialInstance); + builder.build(*_engine, entity); + + return entity; + + } + + CustomGeometry::~CustomGeometry() + { + Log("GEOMETRY DESTRUCTOR"); + _engine->destroy(vertexBuffer); + _engine->destroy(indexBuffer); + } + + void CustomGeometry::computeBoundingBox() + { + float minX = FLT_MAX, minY = FLT_MAX, minZ = FLT_MAX; + float maxX = -FLT_MAX, maxY = -FLT_MAX, maxZ = -FLT_MAX; + + for (uint32_t i = 0; i < numVertices; i += 3) + { + minX = std::min(vertices[i], minX); + minY = std::min(vertices[i + 1], minY); + minZ = std::min(vertices[i + 2], minZ); + maxX = std::max(vertices[i], maxX); + maxY = std::max(vertices[i + 1], maxY); + maxZ = std::max(vertices[i + 2], maxZ); + } + + boundingBox = Box{{minX, minY, minZ}, {maxX, maxY, maxZ}}; + } } // namespace thermion \ No newline at end of file diff --git a/thermion_dart/native/src/FilamentViewer.cpp b/thermion_dart/native/src/FilamentViewer.cpp index 2235a1b7..22e138d5 100644 --- a/thermion_dart/native/src/FilamentViewer.cpp +++ b/thermion_dart/native/src/FilamentViewer.cpp @@ -1206,11 +1206,11 @@ namespace thermion void FilamentViewer::unprojectTexture(EntityId entityId, uint8_t *input, uint32_t inputWidth, uint32_t inputHeight, uint8_t *out, uint32_t outWidth, uint32_t outHeight) { const auto *geometry = _sceneManager->getGeometry(entityId); - if (!geometry->uvs) - { - Log("No UVS"); - return; - } + // if (!geometry->uvs) + // { + // Log("No UVS"); + // return; + // } // UnprojectTexture unproject(geometry, _view->getCamera(), _engine); diff --git a/thermion_dart/native/src/HighlightOverlay.cpp b/thermion_dart/native/src/HighlightOverlay.cpp index 95c6498f..918f41df 100644 --- a/thermion_dart/native/src/HighlightOverlay.cpp +++ b/thermion_dart/native/src/HighlightOverlay.cpp @@ -55,8 +55,6 @@ namespace thermion if (_isGeometryEntity) { - Log("Entity %d is geometry", entityId); - auto geometryEntity = Entity::import(entityId); auto renderable = rm.getInstance(geometryEntity); @@ -74,17 +72,7 @@ namespace thermion auto geometry = sceneManager->getGeometry(entityId); - _entity = utils::EntityManager::get().create(); - RenderableManager::Builder builder(1); - builder.boundingBox(geometry->getBoundingBox()) - .geometry(0, geometry->primitiveType, geometry->vertexBuffer(), geometry->indexBuffer(), 0, geometry->numIndices) - .culling(true) - .material(0, _highlightMaterialInstance) - .priority(0) - .receiveShadows(false) - .castShadows(false); - - builder.build(*engine, _entity); + _entity = geometry->createInstance(materialInstance); scene->addEntity(_entity); auto outlineTransformInstance = tm.getInstance(_entity); diff --git a/thermion_dart/native/src/SceneManager.cpp b/thermion_dart/native/src/SceneManager.cpp index 3d623027..c4844b58 100644 --- a/thermion_dart/native/src/SceneManager.cpp +++ b/thermion_dart/native/src/SceneManager.cpp @@ -412,6 +412,15 @@ namespace thermion { std::lock_guard lock(_mutex); + if(isGeometryEntity(entityId)) { + auto geometry = getGeometry(entityId); + auto materialInstance = createUnlitMaterialInstance(); + auto instanceEntity = geometry->createInstance(materialInstance); + _scene->addEntity(instanceEntity); + + return Entity::smuggle(instanceEntity); + } + const auto &pos = _assets.find(entityId); if (pos == _assets.end()) { @@ -696,9 +705,19 @@ namespace thermion if (isGeometryEntity(entityId)) { + return; + } else if(isGeometryInstance(entityId)) { + // destroy renderable + auto & rm = _engine->getRenderableManager(); + auto & em = _engine->getEntityManager(); + auto instanceEntity = utils::Entity::import(entityId); + auto it = std::find(_geometryInstances.begin(), _geometryInstances.end(), entityId); + _geometryInstances.erase(it); + rm.destroy(instanceEntity); + em.destroy(instanceEntity); + _engine->destroy(instanceEntity); return; - } - + } const auto *instance = getInstanceByEntityId(entityId); if (instance) @@ -2203,7 +2222,17 @@ namespace thermion rm.setPriority(renderableInstance, priority); } - Aabb2 SceneManager::getBoundingBox(View *view, EntityId entityId) + Aabb3 SceneManager::getRenderableBoundingBox(EntityId entityId) { + auto& rm = _engine->getRenderableManager(); + auto instance = rm.getInstance(Entity::import(entityId)); + if(!instance.isValid()) { + return Aabb3 {}; + } + auto box = rm.getAxisAlignedBoundingBox(instance); + return Aabb3 { box.center.x, box.center.y, box.center.z, box.halfExtent.x, box.halfExtent.y, box.halfExtent.z }; + } + + Aabb2 SceneManager::getScreenSpaceBoundingBox(View *view, EntityId entityId) { const auto &camera = view->getCamera(); const auto &viewport = view->getViewport(); @@ -2316,16 +2345,7 @@ namespace thermion bool keepData) { auto geometry = std::make_unique(vertices, numVertices, normals, numNormals, uvs, numUvs, indices, numIndices, primitiveType, _engine); - - auto entity = utils::EntityManager::get().create(); - RenderableManager::Builder builder(1); - - builder.boundingBox(geometry->getBoundingBox()) - .geometry(0, primitiveType, geometry->vertexBuffer(), geometry->indexBuffer(), 0, numIndices) - .culling(true) - .receiveShadows(true) - .castShadows(true); - + filament::Material *mat = nullptr; if (!materialInstance) @@ -2399,16 +2419,14 @@ namespace thermion } } - builder.material(0, materialInstance); - builder.build(*_engine, entity); + auto instanceEntity = geometry->createInstance(materialInstance); + auto instanceEntityId = Entity::smuggle(instanceEntity); + _scene->addEntity(instanceEntity); + _geometryInstances.push_back(instanceEntityId); - _scene->addEntity(entity); + _geometry.emplace(instanceEntityId, std::move(geometry)); - auto entityId = Entity::smuggle(entity); - - _geometry.emplace(entityId, std::move(geometry)); - - return entityId; + return instanceEntityId; } MaterialInstance *SceneManager::getMaterialInstanceAt(EntityId entityId, int materialIndex) diff --git a/thermion_dart/native/src/UnprojectTexture.cpp b/thermion_dart/native/src/UnprojectTexture.cpp index 8af0e664..a8c7126e 100644 --- a/thermion_dart/native/src/UnprojectTexture.cpp +++ b/thermion_dart/native/src/UnprojectTexture.cpp @@ -57,154 +57,154 @@ namespace thermion uint32_t outputWidth, uint32_t outputHeight) { - auto &rm = _engine->getRenderableManager(); + // auto &rm = _engine->getRenderableManager(); - auto &tm = _engine->getTransformManager(); + // auto &tm = _engine->getTransformManager(); - math::mat4 invViewProj = Camera::inverseProjection(_camera.getProjectionMatrix()) * _camera.getModelMatrix(); + // math::mat4 invViewProj = Camera::inverseProjection(_camera.getProjectionMatrix()) * _camera.getModelMatrix(); - auto ti = tm.getInstance(entity); - math::mat4f worldTransform = tm.getWorldTransform(ti); - auto inverseWorldTransform = inverse(worldTransform); + // auto ti = tm.getInstance(entity); + // math::mat4f worldTransform = tm.getWorldTransform(ti); + // auto inverseWorldTransform = inverse(worldTransform); - const float *vertices = _geometry->vertices; - const float *uvs = _geometry->uvs; - const uint16_t *indices = _geometry->indices; - uint32_t numIndices = _geometry->numIndices; + // const float *vertices = _geometry->vertices; + // const float *uvs = _geometry->uvs; + // const uint16_t *indices = _geometry->indices; + // uint32_t numIndices = _geometry->numIndices; - // Create a depth buffer - std::vector depthBuffer(inputWidth * inputHeight, std::numeric_limits::infinity()); + // // Create a depth buffer + // std::vector depthBuffer(inputWidth * inputHeight, std::numeric_limits::infinity()); - // Create a buffer to store the triangle index for each pixel - std::vector triangleIndexBuffer(inputWidth * inputHeight, -1); + // // Create a buffer to store the triangle index for each pixel + // std::vector triangleIndexBuffer(inputWidth * inputHeight, -1); - auto max = 0.0f; - auto min = 99.0f; + // auto max = 0.0f; + // auto min = 99.0f; - // Depth pre-pass - for (size_t i = 0; i < numIndices; i += 3) - { - math::float3 v0(vertices[indices[i] * 3], vertices[indices[i] * 3 + 1], vertices[indices[i] * 3 + 2]); - math::float3 v1(vertices[indices[i + 1] * 3], vertices[indices[i + 1] * 3 + 1], vertices[indices[i + 1] * 3 + 2]); - math::float3 v2(vertices[indices[i + 2] * 3], vertices[indices[i + 2] * 3 + 1], vertices[indices[i + 2] * 3 + 2]); + // // Depth pre-pass + // for (size_t i = 0; i < numIndices; i += 3) + // { + // math::float3 v0(vertices[indices[i] * 3], vertices[indices[i] * 3 + 1], vertices[indices[i] * 3 + 2]); + // math::float3 v1(vertices[indices[i + 1] * 3], vertices[indices[i + 1] * 3 + 1], vertices[indices[i + 1] * 3 + 2]); + // math::float3 v2(vertices[indices[i + 2] * 3], vertices[indices[i + 2] * 3 + 1], vertices[indices[i + 2] * 3 + 2]); - math::float2 uv0(uvs[(indices[i] * 2)], uvs[(indices[i] * 2) + 1]); - math::float2 uv1(uvs[(indices[i + 1] * 2)], uvs[(indices[i + 1] * 2) + 1]); - math::float2 uv2(uvs[(indices[i + 2] * 2)], uvs[(indices[i + 2] * 2) + 1]); + // math::float2 uv0(uvs[(indices[i] * 2)], uvs[(indices[i] * 2) + 1]); + // math::float2 uv1(uvs[(indices[i + 1] * 2)], uvs[(indices[i + 1] * 2) + 1]); + // math::float2 uv2(uvs[(indices[i + 2] * 2)], uvs[(indices[i + 2] * 2) + 1]); - // Transform vertices to world space - v0 = (worldTransform * math::float4(v0, 1.0f)).xyz; - v1 = (worldTransform * math::float4(v1, 1.0f)).xyz; - v2 = (worldTransform * math::float4(v2, 1.0f)).xyz; + // // Transform vertices to world space + // v0 = (worldTransform * math::float4(v0, 1.0f)).xyz; + // v1 = (worldTransform * math::float4(v1, 1.0f)).xyz; + // v2 = (worldTransform * math::float4(v2, 1.0f)).xyz; - // Project vertices to screen space - math::float4 clipPos0 = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(v0, 1.0f); - math::float4 clipPos1 = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(v1, 1.0f); - math::float4 clipPos2 = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(v2, 1.0f); + // // Project vertices to screen space + // math::float4 clipPos0 = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(v0, 1.0f); + // math::float4 clipPos1 = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(v1, 1.0f); + // math::float4 clipPos2 = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(v2, 1.0f); - math::float3 ndcPos0 = clipPos0.xyz / clipPos0.w; - math::float3 ndcPos1 = clipPos1.xyz / clipPos1.w; - math::float3 ndcPos2 = clipPos2.xyz / clipPos2.w; + // math::float3 ndcPos0 = clipPos0.xyz / clipPos0.w; + // math::float3 ndcPos1 = clipPos1.xyz / clipPos1.w; + // math::float3 ndcPos2 = clipPos2.xyz / clipPos2.w; - // Convert NDC to screen coordinates - math::float2 screenPos0((ndcPos0.x * 0.5f + 0.5f) * inputWidth, (1.0f - (ndcPos0.y * 0.5f + 0.5f)) * inputHeight); - math::float2 screenPos1((ndcPos1.x * 0.5f + 0.5f) * inputWidth, (1.0f - (ndcPos1.y * 0.5f + 0.5f)) * inputHeight); - math::float2 screenPos2((ndcPos2.x * 0.5f + 0.5f) * inputWidth, (1.0f - (ndcPos2.y * 0.5f + 0.5f)) * inputHeight); + // // Convert NDC to screen coordinates + // math::float2 screenPos0((ndcPos0.x * 0.5f + 0.5f) * inputWidth, (1.0f - (ndcPos0.y * 0.5f + 0.5f)) * inputHeight); + // math::float2 screenPos1((ndcPos1.x * 0.5f + 0.5f) * inputWidth, (1.0f - (ndcPos1.y * 0.5f + 0.5f)) * inputHeight); + // math::float2 screenPos2((ndcPos2.x * 0.5f + 0.5f) * inputWidth, (1.0f - (ndcPos2.y * 0.5f + 0.5f)) * inputHeight); - // Compute bounding box of the triangle - int minX = std::max(0, static_cast(std::min({screenPos0.x, screenPos1.x, screenPos2.x}))); - int maxX = std::min(static_cast(inputWidth) - 1, static_cast(std::max({screenPos0.x, screenPos1.x, screenPos2.x}))); - int minY = std::max(0, static_cast(std::min({screenPos0.y, screenPos1.y, screenPos2.y}))); - int maxY = std::min(static_cast(inputHeight) - 1, static_cast(std::max({screenPos0.y, screenPos1.y, screenPos2.y}))); + // // Compute bounding box of the triangle + // int minX = std::max(0, static_cast(std::min({screenPos0.x, screenPos1.x, screenPos2.x}))); + // int maxX = std::min(static_cast(inputWidth) - 1, static_cast(std::max({screenPos0.x, screenPos1.x, screenPos2.x}))); + // int minY = std::max(0, static_cast(std::min({screenPos0.y, screenPos1.y, screenPos2.y}))); + // int maxY = std::min(static_cast(inputHeight) - 1, static_cast(std::max({screenPos0.y, screenPos1.y, screenPos2.y}))); - // Iterate over the bounding box - for (int y = minY; y <= maxY; ++y) - { - for (int x = minX; x <= maxX; ++x) - { - math::float2 pixelPos(x + 0.5f, y + 0.5f); + // // Iterate over the bounding box + // for (int y = minY; y <= maxY; ++y) + // { + // for (int x = minX; x <= maxX; ++x) + // { + // math::float2 pixelPos(x + 0.5f, y + 0.5f); - if (isInsideTriangle(pixelPos, screenPos0, screenPos1, screenPos2)) - { - math::float3 bary = barycentric(pixelPos, screenPos0, screenPos1, screenPos2); + // if (isInsideTriangle(pixelPos, screenPos0, screenPos1, screenPos2)) + // { + // math::float3 bary = barycentric(pixelPos, screenPos0, screenPos1, screenPos2); - // Interpolate depth - float depth = bary.x * ndcPos0.z + bary.y * ndcPos1.z + bary.z * ndcPos2.z; + // // Interpolate depth + // float depth = bary.x * ndcPos0.z + bary.y * ndcPos1.z + bary.z * ndcPos2.z; - // Depth test - if (depth < depthBuffer[y * inputWidth + x]) - { + // // Depth test + // if (depth < depthBuffer[y * inputWidth + x]) + // { - if (depth > max) - { - max = depth; - } - if (depth < min) - { - min = depth; - } - depthBuffer[y * inputWidth + x] = depth; - triangleIndexBuffer[y * inputWidth + x] = i / 3; // Store triangle index - } - } - } - } - } + // if (depth > max) + // { + // max = depth; + // } + // if (depth < min) + // { + // min = depth; + // } + // depthBuffer[y * inputWidth + x] = depth; + // triangleIndexBuffer[y * inputWidth + x] = i / 3; // Store triangle index + // } + // } + // } + // } + // } - for (uint32_t y = 0; y < outputHeight; ++y) - { - for (uint32_t x = 0; x < outputWidth; ++x) - { + // for (uint32_t y = 0; y < outputHeight; ++y) + // { + // for (uint32_t x = 0; x < outputWidth; ++x) + // { - math::float2 uv(static_cast(x) / outputWidth, static_cast(y) / outputHeight); + // math::float2 uv(static_cast(x) / outputWidth, static_cast(y) / outputHeight); - // Use the UV coordinates to get the corresponding 3D position on the renderable - math::float3 objectPos; - math::float2 interpolatedUV; - bool found = false; + // // Use the UV coordinates to get the corresponding 3D position on the renderable + // math::float3 objectPos; + // math::float2 interpolatedUV; + // bool found = false; - // Iterate over triangles to find which one contains this UV coordinate - for (size_t i = 0; i < numIndices; i += 3) - { - math::float2 uv0 = *(math::float2 *)&uvs[indices[i] * 2]; - math::float2 uv1 = *(math::float2 *)&uvs[indices[i + 1] * 2]; - math::float2 uv2 = *(math::float2 *)&uvs[indices[i + 2] * 2]; + // // Iterate over triangles to find which one contains this UV coordinate + // for (size_t i = 0; i < numIndices; i += 3) + // { + // math::float2 uv0 = *(math::float2 *)&uvs[indices[i] * 2]; + // math::float2 uv1 = *(math::float2 *)&uvs[indices[i + 1] * 2]; + // math::float2 uv2 = *(math::float2 *)&uvs[indices[i + 2] * 2]; - if (isInsideTriangle(uv, uv0, uv1, uv2)) - { - // Compute barycentric coordinates in UV space - math::float3 bary = barycentric(uv, uv0, uv1, uv2); + // if (isInsideTriangle(uv, uv0, uv1, uv2)) + // { + // // Compute barycentric coordinates in UV space + // math::float3 bary = barycentric(uv, uv0, uv1, uv2); - // Interpolate 3D position - math::float3 v0(vertices[indices[i] * 3], vertices[indices[i] * 3 + 1], vertices[indices[i] * 3 + 2]); - math::float3 v1(vertices[indices[i + 1] * 3], vertices[indices[i + 1] * 3 + 1], vertices[indices[i + 1] * 3 + 2]); - math::float3 v2(vertices[indices[i + 2] * 3], vertices[indices[i + 2] * 3 + 1], vertices[indices[i + 2] * 3 + 2]); + // // Interpolate 3D position + // math::float3 v0(vertices[indices[i] * 3], vertices[indices[i] * 3 + 1], vertices[indices[i] * 3 + 2]); + // math::float3 v1(vertices[indices[i + 1] * 3], vertices[indices[i + 1] * 3 + 1], vertices[indices[i + 1] * 3 + 2]); + // math::float3 v2(vertices[indices[i + 2] * 3], vertices[indices[i + 2] * 3 + 1], vertices[indices[i + 2] * 3 + 2]); - objectPos = v0 * bary.x + v1 * bary.y + v2 * bary.z; - interpolatedUV = uv; + // objectPos = v0 * bary.x + v1 * bary.y + v2 * bary.z; + // interpolatedUV = uv; - // Find the screen coordinates on the input texture - math::float3 worldPos = (worldTransform * math::float4(objectPos, 1.0f)).xyz; - // Project the world position to screen space - math::float4 clipPos = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(worldPos, 1.0f); - math::float3 ndcPos = clipPos.xyz / clipPos.w; - // Convert NDC to screen coordinates - uint32_t screenX = (ndcPos.x * 0.5f + 0.5f) * inputWidth; - uint32_t screenY = (1.0f - (ndcPos.y * 0.5f + 0.5f)) * inputHeight; + // // Find the screen coordinates on the input texture + // math::float3 worldPos = (worldTransform * math::float4(objectPos, 1.0f)).xyz; + // // Project the world position to screen space + // math::float4 clipPos = _camera.getProjectionMatrix() * _camera.getViewMatrix() * math::float4(worldPos, 1.0f); + // math::float3 ndcPos = clipPos.xyz / clipPos.w; + // // Convert NDC to screen coordinates + // uint32_t screenX = (ndcPos.x * 0.5f + 0.5f) * inputWidth; + // uint32_t screenY = (1.0f - (ndcPos.y * 0.5f + 0.5f)) * inputHeight; - if (triangleIndexBuffer[(screenY * inputWidth) + screenX] == i / 3) - { - if (screenX >= 0 && screenX < inputWidth && screenY >= 0 && screenY < inputHeight) - { - int inputIndex = (screenY * inputWidth + screenX) * 4; - int outputIndex = (y * outputWidth + x) * 4; - std::copy_n(&inputTexture[inputIndex], 4, &outputTexture[outputIndex]); - } - } - } - } - } - } + // if (triangleIndexBuffer[(screenY * inputWidth) + screenX] == i / 3) + // { + // if (screenX >= 0 && screenX < inputWidth && screenY >= 0 && screenY < inputHeight) + // { + // int inputIndex = (screenY * inputWidth + screenX) * 4; + // int outputIndex = (y * outputWidth + x) * 4; + // std::copy_n(&inputTexture[inputIndex], 4, &outputTexture[outputIndex]); + // } + // } + // } + // } + // } + // } } } // namespace thermion