From 29c35f903744825ccaec35aa48406968d4e6f5bd Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Wed, 11 Dec 2024 21:06:37 +0800 Subject: [PATCH] refactor: Gizmo internals --- thermion_dart/native/include/scene/Gizmo.hpp | 42 +-- thermion_dart/native/src/scene/Gizmo.cpp | 295 +++---------------- 2 files changed, 71 insertions(+), 266 deletions(-) diff --git a/thermion_dart/native/include/scene/Gizmo.hpp b/thermion_dart/native/include/scene/Gizmo.hpp index 7858502e..20273ba3 100644 --- a/thermion_dart/native/include/scene/Gizmo.hpp +++ b/thermion_dart/native/include/scene/Gizmo.hpp @@ -31,7 +31,12 @@ namespace thermion { public: - Gizmo(Engine *engine, View *view, Scene *scene, Material *material); + Gizmo( + SceneAsset *sceneAsset, + Engine *engine, + View *view, + Scene *scene, + Material *material); ~Gizmo() override; enum Axis @@ -48,15 +53,20 @@ namespace thermion Parent, None }; + + + const Aabb getBoundingBox() const override + { + return Aabb { }; + } typedef void (*GizmoPickCallback)(Gizmo::GizmoPickResultType result, float x, float y, float z); - void pick(uint32_t x, uint32_t y, GizmoPickCallback callback); bool isGizmoEntity(Entity entity); SceneAssetType getType() override { return SceneAssetType::Gizmo; } - utils::Entity getEntity() override { return _entities[0]; } + utils::Entity getEntity() override { return _parent; } bool isInstance() override { return false; } SceneAsset *createInstance(MaterialInstance **materialInstances, size_t materialInstanceCount) override { return nullptr; } MaterialInstance **getMaterialInstances() override { return _materialInstances.data(); } @@ -71,7 +81,6 @@ namespace thermion continue; } scene->addEntity(entity); - } } @@ -126,17 +135,17 @@ namespace thermion { resultType = Gizmo::GizmoPickResultType::Parent; } - else if (result.renderable == _gizmo->_x || result.renderable == _gizmo->_xHitTest) + else if (result.renderable == _gizmo->_x->getEntity()) { resultType = Gizmo::GizmoPickResultType::AxisX; _gizmo->highlight(Gizmo::Axis::X); } - else if (result.renderable == _gizmo->_y || result.renderable == _gizmo->_yHitTest) + else if (result.renderable == _gizmo->_y->getEntity()) { _gizmo->highlight(Gizmo::Axis::Y); resultType = Gizmo::GizmoPickResultType::AxisY; } - else if (result.renderable == _gizmo->_z || result.renderable == _gizmo->_zHitTest) + else if (result.renderable == _gizmo->_z->getEntity()) { _gizmo->highlight(Gizmo::Axis::Z); resultType = Gizmo::GizmoPickResultType::AxisZ; @@ -153,8 +162,7 @@ namespace thermion }; Entity createParentEntity(); - Entity createHitTestEntity(Gizmo::Axis axis, Entity parent); - Entity createAxisEntity(Gizmo::Axis axis, Entity parent); + SceneAsset *createAxisInstance(Gizmo::Axis axis); math::mat4f getRotationForAxis(Gizmo::Axis axis); Entity getEntityForAxis(Gizmo::Axis axis) @@ -162,26 +170,24 @@ namespace thermion switch (axis) { case Gizmo::Axis::X: - return _x; + return _x->getEntity(); case Gizmo::Axis::Y: - return _y; + return _y->getEntity(); case Gizmo::Axis::Z: - return _z; + return _z->getEntity(); } } + SceneAsset *_source; Engine *_engine; Scene *_scene; View *_view; Material *_material; utils::Entity _parent; - utils::Entity _x; - utils::Entity _y; - utils::Entity _z; - utils::Entity _xHitTest; - utils::Entity _yHitTest; - utils::Entity _zHitTest; + SceneAsset *_x; + SceneAsset *_y; + SceneAsset *_z; std::vector _entities; std::vector _materialInstances; diff --git a/thermion_dart/native/src/scene/Gizmo.cpp b/thermion_dart/native/src/scene/Gizmo.cpp index 69a45371..2216c81c 100644 --- a/thermion_dart/native/src/scene/Gizmo.cpp +++ b/thermion_dart/native/src/scene/Gizmo.cpp @@ -10,7 +10,7 @@ #include "scene/Gizmo.hpp" #include "scene/SceneManager.hpp" -#include "material/unlit_fixed_size.h" +#include "material/gizmo.h" #include "Log.hpp" @@ -19,182 +19,62 @@ namespace thermion using namespace filament::gltfio; - // First, create the black cube at the center - // The axes widgets will be parented to this entity - Entity Gizmo::createParentEntity() - { - auto &transformManager = _engine->getTransformManager(); - auto &entityManager = _engine->getEntityManager(); - - auto parent = entityManager.create(); - - // auto *parentMaterialInstance = _material->createInstance(); - // parentMaterialInstance->setParameter("baseColorFactor", math::float4{1.0f, 1.0f, 1.0f, 0.0f}); - // parentMaterialInstance->setParameter("scale", 4.0f); - // parentMaterialInstance->setDoubleSided(false); - - // _materialInstances.push_back(parentMaterialInstance); - - // Create center cube vertices - float centerCubeSize = 0.1f; - float *centerCubeVertices = new float[8 * 3]{ - -centerCubeSize, -centerCubeSize, -centerCubeSize, - centerCubeSize, -centerCubeSize, -centerCubeSize, - centerCubeSize, centerCubeSize, -centerCubeSize, - -centerCubeSize, centerCubeSize, -centerCubeSize, - -centerCubeSize, -centerCubeSize, centerCubeSize, - centerCubeSize, -centerCubeSize, centerCubeSize, - centerCubeSize, centerCubeSize, centerCubeSize, - -centerCubeSize, centerCubeSize, centerCubeSize}; - - // Create center cube indices - uint16_t *centerCubeIndices = new uint16_t[36]{ - 0, 1, 2, 2, 3, 0, - 1, 5, 6, 6, 2, 1, - 5, 4, 7, 7, 6, 5, - 4, 0, 3, 3, 7, 4, - 3, 2, 6, 6, 7, 3, - 4, 5, 1, 1, 0, 4}; - - auto centerCubeVb = VertexBuffer::Builder() - .vertexCount(8) - .bufferCount(1) - .attribute(VertexAttribute::POSITION, 0, VertexBuffer::AttributeType::FLOAT3) - .build(*_engine); - - centerCubeVb->setBufferAt(*_engine, 0, VertexBuffer::BufferDescriptor(centerCubeVertices, 8 * sizeof(filament::math::float3), [](void *buffer, size_t size, void *) - { delete[] static_cast(buffer); })); - - auto centerCubeIb = IndexBuffer::Builder().indexCount(36).bufferType(IndexBuffer::IndexType::USHORT).build(*_engine); - centerCubeIb->setBuffer(*_engine, IndexBuffer::BufferDescriptor( - centerCubeIndices, 36 * sizeof(uint16_t), - [](void *buffer, size_t size, void *) - { delete[] static_cast(buffer); })); - - RenderableManager::Builder(1) - .boundingBox({{-centerCubeSize, -centerCubeSize, -centerCubeSize}, - {centerCubeSize, centerCubeSize, centerCubeSize}}) - // .material(0, parentMaterialInstance) - .layerMask(0xFF, 1u << SceneManager::LAYERS::OVERLAY) - .priority(0) - .geometry(0, RenderableManager::PrimitiveType::TRIANGLES, centerCubeVb, centerCubeIb, 0, 36) - .culling(true) - .build(*_engine, parent); - - auto parentTransformInstance = transformManager.getInstance(parent); - math::mat4f cubeTransform; - transformManager.setTransform(parentTransformInstance, cubeTransform); - return parent; - } - - Gizmo::Gizmo(Engine *engine, View *view, Scene *scene, Material *material) : _engine(engine), _view(view), _scene(scene), _material(material) - { - auto parent = createParentEntity(); - auto x = createAxisEntity(Gizmo::Axis::X, parent); - auto y = createAxisEntity(Gizmo::Axis::Y, parent); - auto z = createAxisEntity(Gizmo::Axis::Z, parent); - - auto xHitTest = createHitTestEntity(Gizmo::Axis::X, parent); - auto yHitTest = createHitTestEntity(Gizmo::Axis::Y, parent); - auto zHitTest = createHitTestEntity(Gizmo::Axis::Z, parent); - - _entities = std::vector{parent, x, y, z, xHitTest, yHitTest, zHitTest}; - _parent = parent; - _x = x; - _y = y; - _z = z; - _xHitTest = xHitTest; - _yHitTest = yHitTest; - _zHitTest = zHitTest; - } - - Entity Gizmo::createAxisEntity(Gizmo::Axis axis, Entity parent) + Gizmo::Gizmo( + SceneAsset *sceneAsset, + Engine *engine, + View *view, + Scene *scene, + Material *material + ) : _source(sceneAsset), + _engine(engine), + _view(view), + _scene(scene), + _material(material) { auto &entityManager = _engine->getEntityManager(); - auto &transformManager = _engine->getTransformManager(); + + _parent = entityManager.create(); + + _z = createAxisInstance(Axis::Z); + _y = createAxisInstance(Axis::Y); + _x = createAxisInstance(Axis::X); + + _entities = std::vector { _parent }; + + for(auto axis : { _z, _y, _x}) { + + for(int i =0; i < axis->getChildEntityCount(); i++) { + auto entity = axis->getChildEntities()[i]; + _entities.push_back(entity); + } + } + + } + + + SceneAsset *Gizmo::createAxisInstance(Gizmo::Axis axis) + { auto *materialInstance = _material->createInstance(); _materialInstances.push_back(materialInstance); - auto entity = entityManager.create(); + auto instance = _source->createInstance(&materialInstance, 1); - auto baseColor = inactiveColors[axis]; + auto box = _source->getBoundingBox(); + Log("BB %f %f %f %f %f %f", box.center(), box.extent().x, box.extent().y, box.extent().z); - // Line and arrow vertices - float lineLength = 0.6f; - float lineWidth = 0.008f; - float arrowLength = 0.06f; - float arrowWidth = 0.02f; - float *vertices = new float[13 * 3]{ - // Line vertices (8 vertices) - -lineWidth, -lineWidth, 0.0f, - lineWidth, -lineWidth, 0.0f, - lineWidth, lineWidth, 0.0f, - -lineWidth, lineWidth, 0.0f, - -lineWidth, -lineWidth, lineLength, - lineWidth, -lineWidth, lineLength, - lineWidth, lineWidth, lineLength, - -lineWidth, lineWidth, lineLength, - // Arrow vertices (5 vertices) - 0.0f, 0.0f, lineLength + arrowLength, // Tip of the arrow - -arrowWidth, -arrowWidth, lineLength, // Base of the arrow - arrowWidth, -arrowWidth, lineLength, - arrowWidth, arrowWidth, lineLength, - -arrowWidth, arrowWidth, lineLength}; - - // Line and arrow indices - uint16_t *indices = new uint16_t[24 + 18]{ - // Line indices (24 indices) - 0, 1, 5, 5, 4, 0, - 1, 2, 6, 6, 5, 1, - 2, 3, 7, 7, 6, 2, - 3, 0, 4, 4, 7, 3, - // // Arrow indices (18 indices) - 8, 9, 10, // Front face - 8, 10, 11, // Right face - 8, 11, 12, // Back face - 8, 12, 9, // Left face - 9, 12, 11, 11, 10, 9 // Base of the arrow - }; - - auto vb = VertexBuffer::Builder() - .vertexCount(13) - .bufferCount(1) - .attribute(VertexAttribute::POSITION, 0, VertexBuffer::AttributeType::FLOAT3) - .build(*_engine); - - vb->setBufferAt(*_engine, 0, VertexBuffer::BufferDescriptor(vertices, 13 * sizeof(filament::math::float3), [](void *buffer, size_t size, void *) - { delete[] static_cast(buffer); })); - - auto ib = IndexBuffer::Builder().indexCount(42).bufferType(IndexBuffer::IndexType::USHORT).build(*_engine); - ib->setBuffer(*_engine, IndexBuffer::BufferDescriptor( - indices, 42 * sizeof(uint16_t), - [](void *buffer, size_t size, void *) - { delete[] static_cast(buffer); })); - - materialInstance->setParameter("baseColorFactor", baseColor); + // Set material properties + materialInstance->setParameter("baseColorFactor", inactiveColors[axis]); materialInstance->setParameter("scale", 4.0f); - materialInstance->setDepthCulling(false); - materialInstance->setDepthFunc(MaterialInstance::DepthFunc::A); + // materialInstance->setParameter("screenSpaceSize", 90.0f); - RenderableManager::Builder(1) - .boundingBox({{-arrowWidth, -arrowWidth, 0}, - {arrowWidth, arrowWidth, lineLength + arrowLength}}) - .material(0, materialInstance) - .geometry(0, RenderableManager::PrimitiveType::TRIANGLES, vb, ib, 0, 42) - .priority(6) - .layerMask(0xFF, 1u << SceneManager::LAYERS::OVERLAY) - .culling(false) - .receiveShadows(false) - .castShadows(false) - .build(*_engine, entity); + auto transform = getRotationForAxis(axis); - auto transformInstance = transformManager.getInstance(entity); + Log("Created axis instance for %d", axis); - transformManager.setTransform(transformInstance, getRotationForAxis(axis)); + auto& tm = _engine->getTransformManager(); + auto transformInstance = tm.getInstance(instance->getEntity()); + tm.setTransform(transformInstance, transform); - // parent the axis to the center cube - auto parentTransformInstance = transformManager.getInstance(parent); - transformManager.setParent(transformInstance, parentTransformInstance); - return entity; + return instance; } Gizmo::~Gizmo() @@ -212,80 +92,6 @@ namespace thermion } } - Entity Gizmo::createHitTestEntity(Gizmo::Axis axis, Entity parent) - { - auto &entityManager = EntityManager::get(); - auto &transformManager = _engine->getTransformManager(); - - auto parentTransformInstance = transformManager.getInstance(parent); - - float volumeWidth = 0.2f; - float volumeLength = 1.2f; - float volumeDepth = 0.2f; - - float *volumeVertices = new float[8 * 3]{ - -volumeWidth / 2, -volumeDepth / 2, 0, - volumeWidth / 2, -volumeDepth / 2, 0, - volumeWidth / 2, -volumeDepth / 2, volumeLength, - -volumeWidth / 2, -volumeDepth / 2, volumeLength, - -volumeWidth / 2, volumeDepth / 2, 0, - volumeWidth / 2, volumeDepth / 2, 0, - volumeWidth / 2, volumeDepth / 2, volumeLength, - -volumeWidth / 2, volumeDepth / 2, volumeLength}; - - uint16_t *volumeIndices = new uint16_t[36]{ - 0, 1, 2, 2, 3, 0, // Bottom face - 4, 5, 6, 6, 7, 4, // Top face - 0, 4, 7, 7, 3, 0, // Left face - 1, 5, 6, 6, 2, 1, // Right face - 0, 1, 5, 5, 4, 0, // Front face - 3, 2, 6, 6, 7, 3 // Back face - }; - - auto volumeVb = VertexBuffer::Builder() - .vertexCount(8) - .bufferCount(1) - .attribute(VertexAttribute::POSITION, 0, VertexBuffer::AttributeType::FLOAT3) - .build(*_engine); - - volumeVb->setBufferAt(*_engine, 0, VertexBuffer::BufferDescriptor(volumeVertices, 8 * sizeof(filament::math::float3), [](void *buffer, size_t size, void *) - { delete[] static_cast(buffer); })); - - auto volumeIb = IndexBuffer::Builder() - .indexCount(36) - .bufferType(IndexBuffer::IndexType::USHORT) - .build(*_engine); - - volumeIb->setBuffer(*_engine, IndexBuffer::BufferDescriptor( - volumeIndices, 36 * sizeof(uint16_t), - [](void *buffer, size_t size, void *) - { delete[] static_cast(buffer); })); - - auto entity = entityManager.create(); - auto *materialInstance = _material->createInstance(); - _materialInstances.push_back(materialInstance); - materialInstance->setParameter("baseColorFactor", math::float4{0.0f, 0.0f, 0.0f, 0.0f}); - materialInstance->setParameter("scale", 4.0f); - materialInstance->setDepthFunc(MaterialInstance::DepthFunc::A); - - RenderableManager::Builder(1) - .boundingBox({{-volumeWidth / 2, -volumeDepth / 2, 0}, {volumeWidth / 2, volumeDepth / 2, volumeLength}}) - .material(0, materialInstance) - .geometry(0, RenderableManager::PrimitiveType::TRIANGLES, volumeVb, volumeIb, 0, 36) - .priority(7) - .layerMask(0xFF, 1u << SceneManager::LAYERS::OVERLAY) - .culling(false) - .receiveShadows(false) - .castShadows(false) - .build(*_engine, entity); - - auto transformInstance = transformManager.getInstance(entity); - transformManager.setTransform(transformInstance, getRotationForAxis(axis)); - // Parent the picking volume to the center cube - transformManager.setParent(transformInstance, parentTransformInstance); - return entity; - } - void Gizmo::highlight(Gizmo::Axis axis) { auto &rm = _engine->getRenderableManager(); @@ -337,14 +143,7 @@ namespace thermion bool Gizmo::isGizmoEntity(Entity e) { - for (int i = 0; i < 7; i++) - { - if (e == _entities[i]) - { - return true; - } - } - return false; + return std::find(_entities.begin(), _entities.end(), e) != _entities.end(); } math::mat4f Gizmo::getRotationForAxis(Gizmo::Axis axis)