From 6b883f335206dc3619467a9a41d291c8d6b31989 Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Thu, 12 Dec 2024 14:19:02 +0800 Subject: [PATCH] chore: update hit test entities used for gizmo --- thermion_dart/native/include/scene/Gizmo.hpp | 108 ++++++++------ thermion_dart/native/src/scene/Gizmo.cpp | 145 ++++++++++++------- 2 files changed, 150 insertions(+), 103 deletions(-) diff --git a/thermion_dart/native/include/scene/Gizmo.hpp b/thermion_dart/native/include/scene/Gizmo.hpp index 20273ba3..d29d912d 100644 --- a/thermion_dart/native/include/scene/Gizmo.hpp +++ b/thermion_dart/native/include/scene/Gizmo.hpp @@ -33,9 +33,9 @@ namespace thermion public: Gizmo( SceneAsset *sceneAsset, - Engine *engine, - View *view, - Scene *scene, + Engine *engine, + View *view, + Scene *scene, Material *material); ~Gizmo() override; @@ -46,7 +46,8 @@ namespace thermion Z }; - enum GizmoPickResultType { + enum GizmoPickResultType + { AxisX, AxisY, AxisZ, @@ -54,12 +55,11 @@ namespace thermion None }; - const Aabb getBoundingBox() const override { - return Aabb { }; + return Aabb{}; } - + typedef void (*GizmoPickCallback)(Gizmo::GizmoPickResultType result, float x, float y, float z); void pick(uint32_t x, uint32_t y, GizmoPickCallback callback); @@ -74,6 +74,7 @@ namespace thermion void addAllEntities(Scene *scene) override { + TRACE("addAllEntities called with %d entities", _entities.size()); for (const auto &entity : _entities) { if (entity.isNull()) @@ -126,32 +127,10 @@ namespace thermion { _gizmo->unhighlight(Gizmo::Axis::X); - _gizmo->unhighlight(Gizmo::Axis::Y); + _gizmo->unhighlight(Gizmo::Axis::Y); _gizmo->unhighlight(Gizmo::Axis::Z); - Gizmo::GizmoPickResultType resultType; - - if (result.renderable == _gizmo->_parent) - { - resultType = Gizmo::GizmoPickResultType::Parent; - } - else if (result.renderable == _gizmo->_x->getEntity()) - { - resultType = Gizmo::GizmoPickResultType::AxisX; - _gizmo->highlight(Gizmo::Axis::X); - } - else if (result.renderable == _gizmo->_y->getEntity()) - { - _gizmo->highlight(Gizmo::Axis::Y); - resultType = Gizmo::GizmoPickResultType::AxisY; - } - else if (result.renderable == _gizmo->_z->getEntity()) - { - _gizmo->highlight(Gizmo::Axis::Z); - resultType = Gizmo::GizmoPickResultType::AxisZ; - } else { - resultType = Gizmo::GizmoPickResultType::None; - } + Gizmo::GizmoPickResultType resultType = _gizmo->getPickResult(result.renderable); _callback(resultType, result.fragCoords.x, result.fragCoords.y, result.fragCoords.z); } @@ -162,22 +141,11 @@ namespace thermion }; Entity createParentEntity(); - SceneAsset *createAxisInstance(Gizmo::Axis axis); + void createAxisInstance(Gizmo::Axis axis); math::mat4f getRotationForAxis(Gizmo::Axis axis); - Entity getEntityForAxis(Gizmo::Axis axis) - { - switch (axis) - { - case Gizmo::Axis::X: - return _x->getEntity(); - case Gizmo::Axis::Y: - return _y->getEntity(); - case Gizmo::Axis::Z: - return _z->getEntity(); - } - } + private: SceneAsset *_source; Engine *_engine; Scene *_scene; @@ -185,9 +153,8 @@ namespace thermion Material *_material; utils::Entity _parent; - SceneAsset *_x; - SceneAsset *_y; - SceneAsset *_z; + std::vector _axes; + std::vector _hitTest; std::vector _entities; std::vector _materialInstances; @@ -202,6 +169,53 @@ namespace thermion math::float4{0.0f, 1.0f, 0.0f, 1.0f}, math::float4{0.0f, 0.0f, 1.0f, 1.0f}, }; + + GizmoPickResultType getPickResult(utils::Entity entity) + { + if (entity.isNull()) + { + return Gizmo::GizmoPickResultType::None; + } + + TRACE("Checking picked entity %d against gizmo axes (axis hit test entities are %d %d %d)", entity, _hitTest[0], _hitTest[1], _hitTest[2]); + + if (entity == _parent) + { + return GizmoPickResultType::Parent; + } + + for (int axisIndex = 0; axisIndex < _axes.size(); axisIndex++) + { + auto axis = _axes[axisIndex]; + TRACE("Checking for axisindex %d", axisIndex); + GizmoPickResultType result = GizmoPickResultType::None; + if (entity == _hitTest[axisIndex]) + { + TRACE("MATCHED AXIS HIT TEST ENTITY for axisIndex %d", axisIndex); + result = GizmoPickResultType(axisIndex); + } + else + { + for (int entityIndex = 0; entityIndex < axis->getChildEntityCount(); entityIndex++) + { + auto childEntity = axis->getChildEntities()[entityIndex]; + if (entity == childEntity) + { + TRACE("MATCHED AXIS CHILD ENTITY at index %d", entityIndex); + result = GizmoPickResultType(axisIndex); + break; + } + } + } + if (result != GizmoPickResultType::None) + { + highlight(Gizmo::Axis(axisIndex)); + return result; + } + } + + return Gizmo::GizmoPickResultType::None; + } }; } \ No newline at end of file diff --git a/thermion_dart/native/src/scene/Gizmo.cpp b/thermion_dart/native/src/scene/Gizmo.cpp index 2216c81c..e5b9c515 100644 --- a/thermion_dart/native/src/scene/Gizmo.cpp +++ b/thermion_dart/native/src/scene/Gizmo.cpp @@ -21,60 +21,87 @@ namespace thermion Gizmo::Gizmo( SceneAsset *sceneAsset, - Engine *engine, - View *view, - Scene *scene, - Material *material - ) : _source(sceneAsset), - _engine(engine), - _view(view), - _scene(scene), - _material(material) + Engine *engine, + View *view, + Scene *scene, + Material *material) : _source(sceneAsset), + _engine(engine), + _view(view), + _scene(scene), + _material(material) { auto &entityManager = _engine->getEntityManager(); _parent = entityManager.create(); + TRACE("Created Gizmo parent entity %d", _parent); + _entities.push_back(_parent); - _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); - } - } - + createAxisInstance(Axis::X); + createAxisInstance(Axis::Y); + createAxisInstance(Axis::Z); } - - SceneAsset *Gizmo::createAxisInstance(Gizmo::Axis axis) + void Gizmo::createAxisInstance(Gizmo::Axis axis) { + auto &rm = _engine->getRenderableManager(); + auto *materialInstance = _material->createInstance(); _materialInstances.push_back(materialInstance); auto instance = _source->createInstance(&materialInstance, 1); - auto box = _source->getBoundingBox(); - Log("BB %f %f %f %f %f %f", box.center(), box.extent().x, box.extent().y, box.extent().z); + TRACE("Created Gizmo axis glTF instance with head entity %d", instance->getEntity()); - // Set material properties materialInstance->setParameter("baseColorFactor", inactiveColors[axis]); materialInstance->setParameter("scale", 4.0f); - // materialInstance->setParameter("screenSpaceSize", 90.0f); + + auto hitTestEntity = instance->findEntityByName("HitTest"); + TRACE("Created hit test entity %d for axis %d", hitTestEntity, axis); + _hitTest.push_back(hitTestEntity); + + if (hitTestEntity.isNull()) + { + TRACE("Hit test entity not found"); + } + else + { + auto renderableInstance = rm.getInstance(hitTestEntity); + if (!renderableInstance.isValid()) + { + TRACE("Failed to find renderable for hit test entity"); + } + else + { + auto *hitTestMaterialInstance = _material->createInstance(); + _materialInstances.push_back(hitTestMaterialInstance); + hitTestMaterialInstance->setParameter("baseColorFactor", math::float4{1.0f, 0.0f, 1.0f, 0.5f}); + hitTestMaterialInstance->setParameter("scale", 4.0f); + rm.setMaterialInstanceAt(renderableInstance, 0, hitTestMaterialInstance); + } + } auto transform = getRotationForAxis(axis); - Log("Created axis instance for %d", axis); + TRACE("Created Gizmo axis instance for axis %d", axis); - auto& tm = _engine->getTransformManager(); + auto &tm = _engine->getTransformManager(); auto transformInstance = tm.getInstance(instance->getEntity()); tm.setTransform(transformInstance, transform); + + // parent this entity's transform to the Gizmo _parent entity + tm.setParent(transformInstance, tm.getInstance(_parent)); - return instance; + _entities.push_back(instance->getEntity()); + + TRACE("Added entity %d for axis %d", instance->getEntity(), axis); + + for (int i = 0; i < instance->getChildEntityCount(); i++) + { + auto entity = instance->getChildEntities()[i]; + _entities.push_back(entity); + TRACE("Added entity %d for axis %d", entity, axis); + } + + _axes.push_back(instance); } Gizmo::~Gizmo() @@ -95,40 +122,46 @@ namespace thermion void Gizmo::highlight(Gizmo::Axis axis) { auto &rm = _engine->getRenderableManager(); - auto entity = getEntityForAxis(axis); - if (entity.isNull()) - { - return; - } - auto renderableInstance = rm.getInstance(entity); + auto instance = _axes[axis]; - if (!renderableInstance.isValid()) + for (int i = 0; i < instance->getChildEntityCount(); i++) { - Log("Invalid renderable for axis"); - return; + auto childEntity = instance->getChildEntities()[i]; + if (childEntity == _hitTest[axis]) + { + continue; + } + auto renderableInstance = rm.getInstance(childEntity); + if (renderableInstance.isValid()) + { + auto *materialInstance = rm.getMaterialInstanceAt(renderableInstance, 0); + math::float4 baseColor = activeColors[axis]; + materialInstance->setParameter("baseColorFactor", baseColor); + } } - auto *materialInstance = rm.getMaterialInstanceAt(renderableInstance, 0); - math::float4 baseColor = activeColors[axis]; - materialInstance->setParameter("baseColorFactor", baseColor); } void Gizmo::unhighlight(Gizmo::Axis axis) { auto &rm = _engine->getRenderableManager(); - auto entity = getEntityForAxis(axis); - if (entity.isNull()) + + auto instance = _axes[axis]; + + for (int i = 0; i < instance->getChildEntityCount(); i++) { - return; + auto childEntity = instance->getChildEntities()[i]; + if (childEntity == _hitTest[axis]) + { + continue; + } + auto renderableInstance = rm.getInstance(childEntity); + if (renderableInstance.isValid()) + { + auto *materialInstance = rm.getMaterialInstanceAt(renderableInstance, 0); + math::float4 baseColor = inactiveColors[axis]; + materialInstance->setParameter("baseColorFactor", baseColor); + } } - auto renderableInstance = rm.getInstance(entity); - if (!renderableInstance.isValid()) - { - Log("Invalid renderable for axis"); - return; - } - auto *materialInstance = rm.getMaterialInstanceAt(renderableInstance, 0); - math::float4 baseColor = inactiveColors[axis]; - materialInstance->setParameter("baseColorFactor", baseColor); } void Gizmo::pick(uint32_t x, uint32_t y, GizmoPickCallback callback)