feat: create transparent overlay for gizmo for easier picking
This commit is contained in:
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:f467a6361958bd8a3381dcd5895665c09932daf37e606b06c7f584de484b0d5d
|
oid sha256:634f5806365b20f05a3736b5b87c1ba6a49b94e39d3defbd6f22f9784d718388
|
||||||
size 1572
|
size 1754
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ class Gizmo {
|
|||||||
Gizmo(Engine& engine, View *view, Scene *scene);
|
Gizmo(Engine& engine, View *view, Scene *scene);
|
||||||
~Gizmo();
|
~Gizmo();
|
||||||
|
|
||||||
void updateTransform();
|
|
||||||
void destroy();
|
void destroy();
|
||||||
Entity x() {
|
Entity x() {
|
||||||
return _entities[0];
|
return _entities[0];
|
||||||
@@ -57,18 +56,21 @@ class Gizmo {
|
|||||||
return _isActive;
|
return _isActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
void highlight(Entity entity);
|
|
||||||
void unhighlight();
|
|
||||||
void pick(uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y));
|
void pick(uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y));
|
||||||
|
bool isGizmoEntity(Entity entity);
|
||||||
|
void setVisibility(bool visible);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void createTransparentRectangles();
|
||||||
|
void highlight(Entity entity);
|
||||||
|
void unhighlight();
|
||||||
Engine &_engine;
|
Engine &_engine;
|
||||||
View *_view;
|
View *_view;
|
||||||
Scene *_scene;
|
Scene *_scene;
|
||||||
Camera *_camera;
|
Camera *_camera;
|
||||||
utils::Entity _entities[4] = { utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity() };
|
utils::Entity _entities[7] = { utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity() };
|
||||||
Material* _material;
|
Material* _material;
|
||||||
MaterialInstance* _materialInstances[4];
|
MaterialInstance* _materialInstances[7];
|
||||||
math::float4 inactiveColors[3] {
|
math::float4 inactiveColors[3] {
|
||||||
math::float4 { 0.75f, 0.0f, 0.0f, 1.0f },
|
math::float4 { 0.75f, 0.0f, 0.0f, 1.0f },
|
||||||
math::float4 { 0.0f, 0.75f, 0.0f, 1.0f },
|
math::float4 { 0.0f, 0.75f, 0.0f, 1.0f },
|
||||||
@@ -80,6 +82,7 @@ class Gizmo {
|
|||||||
math::float4 { 0.0f, 0.0f, 1.0f, 1.0f },
|
math::float4 { 0.0f, 0.0f, 1.0f, 1.0f },
|
||||||
};
|
};
|
||||||
bool _isActive = true;
|
bool _isActive = true;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -8,5 +8,5 @@ GIZMO_PACKAGE:
|
|||||||
GIZMO_GIZMO_OFFSET:
|
GIZMO_GIZMO_OFFSET:
|
||||||
.int 0
|
.int 0
|
||||||
GIZMO_GIZMO_SIZE:
|
GIZMO_GIZMO_SIZE:
|
||||||
.int 26876
|
.int 28800
|
||||||
|
|
||||||
|
|||||||
@@ -8,5 +8,5 @@ _GIZMO_PACKAGE:
|
|||||||
_GIZMO_GIZMO_OFFSET:
|
_GIZMO_GIZMO_OFFSET:
|
||||||
.int 0
|
.int 0
|
||||||
_GIZMO_GIZMO_SIZE:
|
_GIZMO_GIZMO_SIZE:
|
||||||
.int 26876
|
.int 28800
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
|||||||
#include <stdint.h>
|
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
const uint8_t IMAGE_PACKAGE[] = {
|
const uint8_t IMAGE_PACKAGE[] = {
|
||||||
// IMAGE
|
// IMAGE
|
||||||
0x53, 0x52, 0x45, 0x56, 0x5f, 0x54, 0x41, 0x4d, 0x04, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x54, 0x41, 0x45, 0x46,
|
0x53, 0x52, 0x45, 0x56, 0x5f, 0x54, 0x41, 0x4d, 0x04, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x54, 0x41, 0x45, 0x46,
|
||||||
|
|||||||
@@ -45,8 +45,9 @@ Gizmo::Gizmo(Engine &engine, View* view, Scene* scene) : _engine(engine)
|
|||||||
// First, create the black cube at the center
|
// First, create the black cube at the center
|
||||||
// The axes widgets will be parented to this entity
|
// The axes widgets will be parented to this entity
|
||||||
_entities[3] = entityManager.create();
|
_entities[3] = entityManager.create();
|
||||||
|
|
||||||
_materialInstances[3] = _material->createInstance();
|
_materialInstances[3] = _material->createInstance();
|
||||||
_materialInstances[3]->setParameter("color", math::float3{0.0f, 0.0f, 0.0f}); // Black color
|
_materialInstances[3]->setParameter("color", math::float4{0.0f, 0.0f, 0.0f, 1.0f}); // Black color
|
||||||
|
|
||||||
// Create center cube vertices
|
// Create center cube vertices
|
||||||
float centerCubeSize = 0.05f;
|
float centerCubeSize = 0.05f;
|
||||||
@@ -89,7 +90,7 @@ Gizmo::Gizmo(Engine &engine, View* view, Scene* scene) : _engine(engine)
|
|||||||
{centerCubeSize, centerCubeSize, centerCubeSize}})
|
{centerCubeSize, centerCubeSize, centerCubeSize}})
|
||||||
.material(0, _materialInstances[3])
|
.material(0, _materialInstances[3])
|
||||||
.layerMask(0xFF, 2)
|
.layerMask(0xFF, 2)
|
||||||
.priority(7)
|
.priority(6)
|
||||||
.geometry(0, RenderableManager::PrimitiveType::TRIANGLES, centerCubeVb, centerCubeIb, 0, 36)
|
.geometry(0, RenderableManager::PrimitiveType::TRIANGLES, centerCubeVb, centerCubeIb, 0, 36)
|
||||||
.culling(false)
|
.culling(false)
|
||||||
.build(engine, _entities[3]);
|
.build(engine, _entities[3]);
|
||||||
@@ -197,21 +198,21 @@ Gizmo::Gizmo(Engine &engine, View* view, Scene* scene) : _engine(engine)
|
|||||||
transformManager.setParent(instance, cubeTransformInstance);
|
transformManager.setParent(instance, cubeTransformInstance);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_scene->addEntities(_entities,4);
|
|
||||||
|
|
||||||
|
createTransparentRectangles();
|
||||||
|
|
||||||
_view->setLayerEnabled(0, true); // scene assets
|
_view->setLayerEnabled(0, true); // scene assets
|
||||||
_view->setLayerEnabled(1, true); // gizmo
|
_view->setLayerEnabled(1, true); // gizmo
|
||||||
_view->setLayerEnabled(2, true); // world grid
|
_view->setLayerEnabled(2, true); // world grid
|
||||||
}
|
}
|
||||||
|
|
||||||
Gizmo::~Gizmo() {
|
Gizmo::~Gizmo() {
|
||||||
_scene->removeEntities(_entities, 4);
|
_scene->removeEntities(_entities, 7);
|
||||||
for(int i = 0; i < 4; i++) {
|
for(int i = 0; i < 7; i++) {
|
||||||
_engine.destroy(_materialInstances[i]);
|
_engine.destroy(_materialInstances[i]);
|
||||||
}
|
}
|
||||||
_engine.destroy(_material);
|
_engine.destroy(_material);
|
||||||
for(int i = 0; i < 4; i++) {
|
for(int i = 0; i < 7; i++) {
|
||||||
_engine.destroy(_entities[i]);
|
_engine.destroy(_entities[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,6 +222,95 @@ Gizmo::~Gizmo() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Gizmo::createTransparentRectangles()
|
||||||
|
{
|
||||||
|
auto &entityManager = EntityManager::get();
|
||||||
|
auto &transformManager = _engine.getTransformManager();
|
||||||
|
|
||||||
|
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<float *>(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<uint16_t *>(buffer); }
|
||||||
|
));
|
||||||
|
|
||||||
|
for (int i = 4; i < 7; i++)
|
||||||
|
{
|
||||||
|
_entities[i] = entityManager.create();
|
||||||
|
_materialInstances[i] = _material->createInstance();
|
||||||
|
|
||||||
|
_materialInstances[i]->setParameter("color", math::float4{0.0f, 0.0f, 0.0f, 0.0f});
|
||||||
|
|
||||||
|
math::mat4f transform;
|
||||||
|
switch (i-4)
|
||||||
|
{
|
||||||
|
case Axis::X:
|
||||||
|
transform = math::mat4f::rotation(math::F_PI_2, math::float3{0, 1, 0});
|
||||||
|
break;
|
||||||
|
case Axis::Y:
|
||||||
|
transform = math::mat4f::rotation(-math::F_PI_2, math::float3{1, 0, 0});
|
||||||
|
break;
|
||||||
|
case Axis::Z:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderableManager::Builder(1)
|
||||||
|
.boundingBox({{-volumeWidth / 2, -volumeDepth / 2, 0}, {volumeWidth / 2, volumeDepth / 2, volumeLength}})
|
||||||
|
.material(0, _materialInstances[i])
|
||||||
|
.geometry(0, RenderableManager::PrimitiveType::TRIANGLES, volumeVb, volumeIb, 0, 36)
|
||||||
|
.priority(7)
|
||||||
|
.layerMask(0xFF, 2)
|
||||||
|
.culling(false)
|
||||||
|
.receiveShadows(false)
|
||||||
|
.castShadows(false)
|
||||||
|
.build(_engine, _entities[i]);
|
||||||
|
|
||||||
|
auto instance = transformManager.getInstance(_entities[i]);
|
||||||
|
transformManager.setTransform(instance, transform);
|
||||||
|
|
||||||
|
// Parent the picking volume to the center cube
|
||||||
|
transformManager.setParent(instance, transformManager.getInstance(_entities[3]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Gizmo::highlight(Entity entity) {
|
void Gizmo::highlight(Entity entity) {
|
||||||
auto &rm = _engine.getRenderableManager();
|
auto &rm = _engine.getRenderableManager();
|
||||||
auto renderableInstance = rm.getInstance(entity);
|
auto renderableInstance = rm.getInstance(entity);
|
||||||
@@ -270,73 +360,37 @@ void Gizmo::destroy()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Gizmo::updateTransform()
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
// auto & transformManager = _engine.getTransformManager();
|
|
||||||
// auto transformInstance = transformManager.getInstance(_entities[3]);
|
|
||||||
|
|
||||||
// if(!transformInstance.isValid()) {
|
|
||||||
// Log("No valid gizmo transform");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// auto worldTransform = transformManager.getWorldTransform(transformInstance);
|
|
||||||
// math::float4 worldPosition { 0.0f, 0.0f, 0.0f, 1.0f };
|
|
||||||
// worldPosition = worldTransform * worldPosition;
|
|
||||||
|
|
||||||
// // Calculate distance
|
|
||||||
// float distance = length(worldPosition.xyz - camera.getPosition());
|
|
||||||
|
|
||||||
// const float desiredScreenSize = 3.0f; // Desired height in pixels
|
|
||||||
// const float baseSize = 0.1f; // Base size in world units
|
|
||||||
|
|
||||||
// // Get the vertical field of view of the camera (assuming it's in radians)
|
|
||||||
// float fovY = camera.getFieldOfViewInDegrees(filament::Camera::Fov::VERTICAL);
|
|
||||||
|
|
||||||
// // Calculate the scale needed to maintain the desired screen size
|
|
||||||
// float newScale = (2.0f * distance * tan(fovY * 0.5f) * desiredScreenSize) / (baseSize * vp.height);
|
|
||||||
|
|
||||||
// if(std::isnan(newScale)) {
|
|
||||||
// newScale = 1.0f;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Log("Distance %f, newscale %f", distance, newScale);
|
|
||||||
|
|
||||||
// auto localTransform = transformManager.getTransform(transformInstance);
|
|
||||||
|
|
||||||
// // Apply scale to gizmo
|
|
||||||
// math::float3 translation;
|
|
||||||
// math::quatf rotation;
|
|
||||||
// math::float3 scale;
|
|
||||||
|
|
||||||
// decomposeMatrix(localTransform, &translation, &rotation, &scale);
|
|
||||||
|
|
||||||
// scale = math::float3 { newScale, newScale, newScale };
|
|
||||||
|
|
||||||
// auto scaledTransform = composeMatrix(translation, rotation, scale);
|
|
||||||
|
|
||||||
// transformManager.setTransform(transformInstance, scaledTransform);
|
|
||||||
|
|
||||||
// auto viewSpacePos = camera.getViewMatrix() * worldPosition;
|
|
||||||
// math::float4 entityScreenPos = camera.getProjectionMatrix() * viewSpacePos;
|
|
||||||
// entityScreenPos /= entityScreenPos.w;
|
|
||||||
// float screenX = (entityScreenPos.x * 0.5f + 0.5f) * vp.width;
|
|
||||||
// float screenY = (entityScreenPos.y * 0.5f + 0.5f) * vp.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Gizmo::pick(uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y))
|
void Gizmo::pick(uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y))
|
||||||
{
|
{
|
||||||
auto * gizmo = this;
|
auto * gizmo = this;
|
||||||
_view->pick(x, y, [=](filament::View::PickingQueryResult const &result) {
|
_view->pick(x, y, [=](filament::View::PickingQueryResult const &result) {
|
||||||
if(result.renderable == gizmo->x() || result.renderable == gizmo->y() || result.renderable == gizmo->z()) {
|
for(int i = 4; i < 7; i++) {
|
||||||
gizmo->highlight(result.renderable);
|
if(_entities[i] == result.renderable) {
|
||||||
callback(Entity::smuggle(result.renderable), x, y);
|
gizmo->highlight(_entities[i - 4]);
|
||||||
} else {
|
callback(Entity::smuggle(_entities[i - 4]), x, y);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
gizmo->unhighlight();
|
gizmo->unhighlight();
|
||||||
}
|
callback(0, x, y);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Gizmo::isGizmoEntity(Entity e) {
|
||||||
|
for(int i = 0; i < 7; i++) {
|
||||||
|
if(e == _entities[i]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gizmo::setVisibility(bool visible) {
|
||||||
|
if(visible) {
|
||||||
|
_scene->addEntities(_entities, 7);
|
||||||
|
} else {
|
||||||
|
_scene->removeEntities(_entities, 7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user