feat: add rotation gizmo
This commit is contained in:
@@ -128,6 +128,10 @@ class GizmoInputHandler extends InputHandler {
|
|||||||
final InputHandler wrapped;
|
final InputHandler wrapped;
|
||||||
final ThermionViewer viewer;
|
final ThermionViewer viewer;
|
||||||
late final _Gizmo translationGizmo;
|
late final _Gizmo translationGizmo;
|
||||||
|
late final _Gizmo rotationGizmo;
|
||||||
|
_Gizmo get active =>
|
||||||
|
type == GizmoType.translation ? translationGizmo : rotationGizmo;
|
||||||
|
GizmoType type = GizmoType.translation;
|
||||||
|
|
||||||
Stream<({ThermionEntity entity, Matrix4 transform})>
|
Stream<({ThermionEntity entity, Matrix4 transform})>
|
||||||
get onEntityTransformUpdated =>
|
get onEntityTransformUpdated =>
|
||||||
@@ -145,9 +149,12 @@ class GizmoInputHandler extends InputHandler {
|
|||||||
}
|
}
|
||||||
await viewer.initialized;
|
await viewer.initialized;
|
||||||
final view = await viewer.getViewAt(0);
|
final view = await viewer.getViewAt(0);
|
||||||
var translationGizmoAsset =
|
|
||||||
await viewer.createGizmo(view, GizmoType.translation);
|
var tg = await viewer.createGizmo(view, GizmoType.translation);
|
||||||
this.translationGizmo = _Gizmo(translationGizmoAsset, viewer);
|
this.translationGizmo = _Gizmo(tg, viewer);
|
||||||
|
var rg = await viewer.createGizmo(view, GizmoType.rotation);
|
||||||
|
this.rotationGizmo = _Gizmo(rg, viewer);
|
||||||
|
|
||||||
_initialized.complete(true);
|
_initialized.complete(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,6 +163,7 @@ class GizmoInputHandler extends InputHandler {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future dispose() async {
|
Future dispose() async {
|
||||||
|
await viewer.removeEntity(rotationGizmo._gizmo);
|
||||||
await viewer.removeEntity(translationGizmo._gizmo);
|
await viewer.removeEntity(translationGizmo._gizmo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,13 +200,13 @@ class GizmoInputHandler extends InputHandler {
|
|||||||
|
|
||||||
await viewer.pick(localPosition.x.toInt(), localPosition.y.toInt(),
|
await viewer.pick(localPosition.x.toInt(), localPosition.y.toInt(),
|
||||||
(result) async {
|
(result) async {
|
||||||
if (translationGizmo._gizmo.isNonPickable(result.entity) ||
|
if (active._gizmo.isNonPickable(result.entity) ||
|
||||||
result.entity == FILAMENT_ENTITY_NULL) {
|
result.entity == FILAMENT_ENTITY_NULL) {
|
||||||
await translationGizmo.detach();
|
await active.detach();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!translationGizmo._gizmo.isGizmoEntity(result.entity)) {
|
if (!active._gizmo.isGizmoEntity(result.entity)) {
|
||||||
translationGizmo.attach(result.entity);
|
active.attach(result.entity);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -208,19 +216,19 @@ class GizmoInputHandler extends InputHandler {
|
|||||||
if (!_initialized.isCompleted) {
|
if (!_initialized.isCompleted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
translationGizmo.checkHover(
|
active.checkHover(
|
||||||
localPosition.x.floor(), localPosition.y.floor());
|
localPosition.x.floor(), localPosition.y.floor());
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onPointerMove(
|
Future<void> onPointerMove(
|
||||||
Vector2 localPosition, Vector2 delta, bool isMiddle) async {
|
Vector2 localPosition, Vector2 delta, bool isMiddle) async {
|
||||||
if (!isMiddle && translationGizmo._active != null) {
|
if (!isMiddle && active._active != null) {
|
||||||
final scaledDelta = Vector2(
|
final scaledDelta = Vector2(
|
||||||
delta.x,
|
delta.x,
|
||||||
delta.y,
|
delta.y,
|
||||||
);
|
);
|
||||||
translationGizmo._updateTransform(localPosition, scaledDelta);
|
active._updateTransform(localPosition, scaledDelta);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return wrapped.onPointerMove(localPosition, delta, isMiddle);
|
return wrapped.onPointerMove(localPosition, delta, isMiddle);
|
||||||
@@ -268,21 +276,19 @@ class GizmoInputHandler extends InputHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future detach(ThermionAsset asset) async {
|
Future detach(ThermionAsset asset) async {
|
||||||
|
if (active._attachedTo == asset.entity) {
|
||||||
if (translationGizmo._attachedTo == asset.entity) {
|
await active.detach();
|
||||||
await translationGizmo.detach();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final childEntities = await asset.getChildEntities();
|
final childEntities = await asset.getChildEntities();
|
||||||
for(final childEntity in childEntities) {
|
for (final childEntity in childEntities) {
|
||||||
if(translationGizmo._attachedTo == childEntity) {
|
if (active._attachedTo == childEntity) {
|
||||||
await translationGizmo.detach();
|
await active.detach();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @override
|
// @override
|
||||||
// Future setCamera(Camera camera) async {
|
// Future setCamera(Camera camera) async {
|
||||||
// await wrapped.setCamera(camera);
|
// await wrapped.setCamera(camera);
|
||||||
|
|||||||
@@ -1388,17 +1388,35 @@ external void remove_skybox_render_thread(
|
|||||||
ffi.Pointer<TSceneManager>,
|
ffi.Pointer<TSceneManager>,
|
||||||
ffi.Pointer<TView>,
|
ffi.Pointer<TView>,
|
||||||
ffi.Pointer<TScene>,
|
ffi.Pointer<TScene>,
|
||||||
|
ffi.UnsignedInt,
|
||||||
ffi.Pointer<
|
ffi.Pointer<
|
||||||
ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TGizmo>)>>)>(
|
ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TGizmo>)>>)>(
|
||||||
isLeaf: true)
|
symbol: "SceneManager_createGizmoRenderThread", isLeaf: true)
|
||||||
external ffi.Pointer<TGizmo> SceneManager_createGizmoRenderThread(
|
external ffi.Pointer<TGizmo> _SceneManager_createGizmoRenderThread(
|
||||||
ffi.Pointer<TSceneManager> tSceneManager,
|
ffi.Pointer<TSceneManager> tSceneManager,
|
||||||
ffi.Pointer<TView> tView,
|
ffi.Pointer<TView> tView,
|
||||||
ffi.Pointer<TScene> tScene,
|
ffi.Pointer<TScene> tScene,
|
||||||
|
int tGizmoType,
|
||||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TGizmo>)>>
|
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TGizmo>)>>
|
||||||
onComplete,
|
onComplete,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ffi.Pointer<TGizmo> SceneManager_createGizmoRenderThread(
|
||||||
|
ffi.Pointer<TSceneManager> tSceneManager,
|
||||||
|
ffi.Pointer<TView> tView,
|
||||||
|
ffi.Pointer<TScene> tScene,
|
||||||
|
TGizmoType tGizmoType,
|
||||||
|
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<TGizmo>)>>
|
||||||
|
onComplete,
|
||||||
|
) =>
|
||||||
|
_SceneManager_createGizmoRenderThread(
|
||||||
|
tSceneManager,
|
||||||
|
tView,
|
||||||
|
tScene,
|
||||||
|
tGizmoType.value,
|
||||||
|
onComplete,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(
|
ffi.Void Function(
|
||||||
ffi.Pointer<TSceneManager>,
|
ffi.Pointer<TSceneManager>,
|
||||||
@@ -1688,14 +1706,31 @@ external void unproject_texture_render_thread(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Pointer<TGizmo> Function(ffi.Pointer<TSceneManager>, ffi.Pointer<TView>,
|
ffi.Pointer<TGizmo> Function(
|
||||||
ffi.Pointer<TScene>)>(isLeaf: true)
|
ffi.Pointer<TSceneManager>,
|
||||||
external ffi.Pointer<TGizmo> SceneManager_createGizmo(
|
ffi.Pointer<TView>,
|
||||||
|
ffi.Pointer<TScene>,
|
||||||
|
ffi.UnsignedInt)>(symbol: "SceneManager_createGizmo", isLeaf: true)
|
||||||
|
external ffi.Pointer<TGizmo> _SceneManager_createGizmo(
|
||||||
ffi.Pointer<TSceneManager> tSceneManager,
|
ffi.Pointer<TSceneManager> tSceneManager,
|
||||||
ffi.Pointer<TView> tView,
|
ffi.Pointer<TView> tView,
|
||||||
ffi.Pointer<TScene> tScene,
|
ffi.Pointer<TScene> tScene,
|
||||||
|
int tGizmoType,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ffi.Pointer<TGizmo> SceneManager_createGizmo(
|
||||||
|
ffi.Pointer<TSceneManager> tSceneManager,
|
||||||
|
ffi.Pointer<TView> tView,
|
||||||
|
ffi.Pointer<TScene> tScene,
|
||||||
|
TGizmoType tGizmoType,
|
||||||
|
) =>
|
||||||
|
_SceneManager_createGizmo(
|
||||||
|
tSceneManager,
|
||||||
|
tView,
|
||||||
|
tScene,
|
||||||
|
tGizmoType.value,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Pointer<TSceneAsset> Function(
|
ffi.Pointer<TSceneAsset> Function(
|
||||||
ffi.Pointer<TSceneManager>,
|
ffi.Pointer<TSceneManager>,
|
||||||
@@ -2487,6 +2522,20 @@ final class Aabb3 extends ffi.Struct {
|
|||||||
external double halfExtentZ;
|
external double halfExtentZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum TGizmoType {
|
||||||
|
TRANSLATION(0),
|
||||||
|
ROTATION(1);
|
||||||
|
|
||||||
|
final int value;
|
||||||
|
const TGizmoType(this.value);
|
||||||
|
|
||||||
|
static TGizmoType fromValue(int value) => switch (value) {
|
||||||
|
0 => TRANSLATION,
|
||||||
|
1 => ROTATION,
|
||||||
|
_ => throw ArgumentError("Unknown value for TGizmoType: $value"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
enum TSamplerCompareFunc {
|
enum TSamplerCompareFunc {
|
||||||
/// !< Less or equal
|
/// !< Less or equal
|
||||||
LE(0),
|
LE(0),
|
||||||
|
|||||||
@@ -2066,7 +2066,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
var scene = View_getScene(view.view);
|
var scene = View_getScene(view.view);
|
||||||
final gizmo = await withPointerCallback<TGizmo>((cb) {
|
final gizmo = await withPointerCallback<TGizmo>((cb) {
|
||||||
SceneManager_createGizmoRenderThread(
|
SceneManager_createGizmoRenderThread(
|
||||||
_sceneManager!, view.view, scene, cb);
|
_sceneManager!, view.view, scene, TGizmoType.values[gizmoType.index], cb);
|
||||||
});
|
});
|
||||||
if (gizmo == nullptr) {
|
if (gizmo == nullptr) {
|
||||||
throw Exception("Failed to create gizmo");
|
throw Exception("Failed to create gizmo");
|
||||||
|
|||||||
@@ -124,6 +124,11 @@ extern "C"
|
|||||||
|
|
||||||
typedef struct Aabb3 Aabb3;
|
typedef struct Aabb3 Aabb3;
|
||||||
|
|
||||||
|
enum TGizmoType {
|
||||||
|
TRANSLATION,
|
||||||
|
ROTATION
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -11,7 +11,7 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE TGizmo *SceneManager_createGizmo(TSceneManager *tSceneManager, TView *tView, TScene *tScene);
|
EMSCRIPTEN_KEEPALIVE TGizmo *SceneManager_createGizmo(TSceneManager *tSceneManager, TView *tView, TScene *tScene, TGizmoType tGizmoType);
|
||||||
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneManager_createGeometry(
|
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneManager_createGeometry(
|
||||||
TSceneManager *sceneManager,
|
TSceneManager *sceneManager,
|
||||||
float *vertices,
|
float *vertices,
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ namespace thermion
|
|||||||
TSceneManager *tSceneManager,
|
TSceneManager *tSceneManager,
|
||||||
TView *tView,
|
TView *tView,
|
||||||
TScene *tScene,
|
TScene *tScene,
|
||||||
|
TGizmoType tGizmoType,
|
||||||
void (*onComplete)(TGizmo*)
|
void (*onComplete)(TGizmo*)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -8,5 +8,5 @@ ROTATION_GIZMO_GLB_PACKAGE:
|
|||||||
ROTATION_GIZMO_GLB_ROTATION_GIZMO_OFFSET:
|
ROTATION_GIZMO_GLB_ROTATION_GIZMO_OFFSET:
|
||||||
.int 0
|
.int 0
|
||||||
ROTATION_GIZMO_GLB_ROTATION_GIZMO_SIZE:
|
ROTATION_GIZMO_GLB_ROTATION_GIZMO_SIZE:
|
||||||
.int 156056
|
.int 78876
|
||||||
|
|
||||||
|
|||||||
@@ -8,5 +8,5 @@ _ROTATION_GIZMO_GLB_PACKAGE:
|
|||||||
_ROTATION_GIZMO_GLB_ROTATION_GIZMO_OFFSET:
|
_ROTATION_GIZMO_GLB_ROTATION_GIZMO_OFFSET:
|
||||||
.int 0
|
.int 0
|
||||||
_ROTATION_GIZMO_GLB_ROTATION_GIZMO_SIZE:
|
_ROTATION_GIZMO_GLB_ROTATION_GIZMO_SIZE:
|
||||||
.int 156056
|
.int 78876
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -36,7 +36,10 @@ namespace thermion
|
|||||||
Engine *engine,
|
Engine *engine,
|
||||||
View *view,
|
View *view,
|
||||||
Scene *scene,
|
Scene *scene,
|
||||||
Material *material);
|
Material *material) noexcept;
|
||||||
|
|
||||||
|
Gizmo(Gizmo &&other) noexcept;
|
||||||
|
|
||||||
~Gizmo() override;
|
~Gizmo() override;
|
||||||
|
|
||||||
enum Axis
|
enum Axis
|
||||||
@@ -152,6 +155,8 @@ namespace thermion
|
|||||||
View *_view;
|
View *_view;
|
||||||
Material *_material;
|
Material *_material;
|
||||||
|
|
||||||
|
float _scale = 8.0f;
|
||||||
|
|
||||||
utils::Entity _parent;
|
utils::Entity _parent;
|
||||||
std::vector<SceneAsset *> _axes;
|
std::vector<SceneAsset *> _axes;
|
||||||
std::vector<utils::Entity> _hitTest;
|
std::vector<utils::Entity> _hitTest;
|
||||||
@@ -177,7 +182,7 @@ namespace thermion
|
|||||||
return Gizmo::GizmoPickResultType::None;
|
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]);
|
TRACE("Checking picked entity %d against gizmo axes with (%d axis hit test entities : %d %d %d)", entity, _hitTest.size(), _hitTest[0], _hitTest[1], _hitTest[2]);
|
||||||
|
|
||||||
if (entity == _parent)
|
if (entity == _parent)
|
||||||
{
|
{
|
||||||
@@ -187,7 +192,7 @@ namespace thermion
|
|||||||
for (int axisIndex = 0; axisIndex < _axes.size(); axisIndex++)
|
for (int axisIndex = 0; axisIndex < _axes.size(); axisIndex++)
|
||||||
{
|
{
|
||||||
auto axis = _axes[axisIndex];
|
auto axis = _axes[axisIndex];
|
||||||
TRACE("Checking for axisindex %d", axisIndex);
|
TRACE("Checking for axisindex %d with %d child entities", axisIndex, axis->getChildEntityCount());
|
||||||
GizmoPickResultType result = GizmoPickResultType::None;
|
GizmoPickResultType result = GizmoPickResultType::None;
|
||||||
if (entity == _hitTest[axisIndex])
|
if (entity == _hitTest[axisIndex])
|
||||||
{
|
{
|
||||||
@@ -196,14 +201,21 @@ namespace thermion
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int entityIndex = 0; entityIndex < axis->getChildEntityCount(); entityIndex++)
|
if(entity == axis->getEntity()) {
|
||||||
{
|
TRACE("MATCHED AXIS HEAD ENTITY");
|
||||||
auto childEntity = axis->getChildEntities()[entityIndex];
|
result = GizmoPickResultType(axisIndex);
|
||||||
if (entity == childEntity)
|
} else {
|
||||||
|
for (int entityIndex = 0; entityIndex < axis->getChildEntityCount(); entityIndex++)
|
||||||
{
|
{
|
||||||
TRACE("MATCHED AXIS CHILD ENTITY at index %d", entityIndex);
|
auto childEntity = axis->getChildEntities()[entityIndex];
|
||||||
result = GizmoPickResultType(axisIndex);
|
|
||||||
break;
|
if (entity == childEntity)
|
||||||
|
{
|
||||||
|
TRACE("MATCHED AXIS CHILD ENTITY %d (index %d)", childEntity, entityIndex);
|
||||||
|
result = GizmoPickResultType(axisIndex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
TRACE("Failed to match entity %d against axis child entity %d", entity, childEntity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,11 @@ namespace thermion
|
|||||||
OVERLAY = 7,
|
OVERLAY = 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum GizmoType {
|
||||||
|
TRANSLATION,
|
||||||
|
ROTATION
|
||||||
|
};
|
||||||
|
|
||||||
////
|
////
|
||||||
/// @brief Load the glTF file from the specified path and adds all entities to the scene.
|
/// @brief Load the glTF file from the specified path and adds all entities to the scene.
|
||||||
/// @param uri the path to the asset. Should be either asset:// (representing a Flutter asset), or file:// (representing a filesystem file).
|
/// @param uri the path to the asset. Should be either asset:// (representing a Flutter asset), or file:// (representing a filesystem file).
|
||||||
@@ -277,7 +282,7 @@ namespace thermion
|
|||||||
/// @param view
|
/// @param view
|
||||||
/// @param scene
|
/// @param scene
|
||||||
/// @return
|
/// @return
|
||||||
Gizmo *createGizmo(View *view, Scene *scene);
|
Gizmo *createGizmo(View *view, Scene *scene, GizmoType type);
|
||||||
|
|
||||||
|
|
||||||
/// @brief
|
/// @brief
|
||||||
@@ -323,7 +328,8 @@ namespace thermion
|
|||||||
Material *_unlitFixedSizeMaterial = nullptr;
|
Material *_unlitFixedSizeMaterial = nullptr;
|
||||||
Material *_gizmoMaterial = nullptr;
|
Material *_gizmoMaterial = nullptr;
|
||||||
|
|
||||||
SceneAsset *_gizmoGlb;
|
SceneAsset *_translationGizmoGlb;
|
||||||
|
SceneAsset *_rotationGizmoGlb;
|
||||||
|
|
||||||
utils::NameComponentManager *_ncm;
|
utils::NameComponentManager *_ncm;
|
||||||
|
|
||||||
|
|||||||
@@ -30,12 +30,12 @@ extern "C"
|
|||||||
return reinterpret_cast<TMaterialProvider*>(provider);
|
return reinterpret_cast<TMaterialProvider*>(provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE TGizmo *SceneManager_createGizmo(TSceneManager *tSceneManager, TView *tView, TScene *tScene)
|
EMSCRIPTEN_KEEPALIVE TGizmo *SceneManager_createGizmo(TSceneManager *tSceneManager, TView *tView, TScene *tScene, TGizmoType tGizmoType)
|
||||||
{
|
{
|
||||||
auto sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
|
auto sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
|
||||||
auto *scene = reinterpret_cast<Scene *>(tScene);
|
auto *scene = reinterpret_cast<Scene *>(tScene);
|
||||||
auto *view = reinterpret_cast<View *>(tView);
|
auto *view = reinterpret_cast<View *>(tView);
|
||||||
auto gizmo = sceneManager->createGizmo(view, scene);
|
auto gizmo = sceneManager->createGizmo(view, scene, static_cast<SceneManager::GizmoType>(tGizmoType));
|
||||||
return reinterpret_cast<TGizmo *>(gizmo);
|
return reinterpret_cast<TGizmo *>(gizmo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -81,12 +81,11 @@ extern "C"
|
|||||||
const auto child = Entity::import(childId);
|
const auto child = Entity::import(childId);
|
||||||
const auto parent = Entity::import(parentId);
|
const auto parent = Entity::import(parentId);
|
||||||
|
|
||||||
|
|
||||||
const auto &childInstance = tm->getInstance(child);
|
const auto &childInstance = tm->getInstance(child);
|
||||||
|
|
||||||
if (!childInstance.isValid())
|
if (!childInstance.isValid())
|
||||||
{
|
{
|
||||||
Log("Child instance is not valid");
|
TRACE("Can't set transform parent, child instance is not valid");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -540,12 +540,13 @@ extern "C"
|
|||||||
TSceneManager *tSceneManager,
|
TSceneManager *tSceneManager,
|
||||||
TView *tView,
|
TView *tView,
|
||||||
TScene *tScene,
|
TScene *tScene,
|
||||||
|
TGizmoType tGizmoType,
|
||||||
void (*onComplete)(TGizmo*)
|
void (*onComplete)(TGizmo*)
|
||||||
) {
|
) {
|
||||||
std::packaged_task<void()> lambda(
|
std::packaged_task<void()> lambda(
|
||||||
[=]() mutable
|
[=]() mutable
|
||||||
{
|
{
|
||||||
auto *gizmo = SceneManager_createGizmo(tSceneManager, tView, tScene);
|
auto *gizmo = SceneManager_createGizmo(tSceneManager, tView, tScene, tGizmoType);
|
||||||
onComplete(gizmo);
|
onComplete(gizmo);
|
||||||
});
|
});
|
||||||
auto fut = _rl->add_task(lambda);
|
auto fut = _rl->add_task(lambda);
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace thermion
|
|||||||
Engine *engine,
|
Engine *engine,
|
||||||
View *view,
|
View *view,
|
||||||
Scene *scene,
|
Scene *scene,
|
||||||
Material *material) : _source(sceneAsset),
|
Material *material) noexcept : _source(sceneAsset),
|
||||||
_engine(engine),
|
_engine(engine),
|
||||||
_view(view),
|
_view(view),
|
||||||
_scene(scene),
|
_scene(scene),
|
||||||
@@ -41,6 +41,27 @@ namespace thermion
|
|||||||
createAxisInstance(Axis::Z);
|
createAxisInstance(Axis::Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// move constructor so we don't re-create all entities/materials when moving
|
||||||
|
Gizmo::Gizmo(Gizmo &&other) noexcept : _source(other._source),
|
||||||
|
_engine(other._engine),
|
||||||
|
_view(other._view),
|
||||||
|
_scene(other._scene),
|
||||||
|
_material(other._material),
|
||||||
|
_parent(other._parent),
|
||||||
|
_scale(other._scale),
|
||||||
|
_entities(std::move(other._entities)),
|
||||||
|
_materialInstances(std::move(other._materialInstances)),
|
||||||
|
_hitTest(std::move(other._hitTest)),
|
||||||
|
_axes(std::move(other._axes))
|
||||||
|
{
|
||||||
|
other._source = nullptr;
|
||||||
|
other._engine = nullptr;
|
||||||
|
other._view = nullptr;
|
||||||
|
other._scene = nullptr;
|
||||||
|
other._material = nullptr;
|
||||||
|
other._parent = {};
|
||||||
|
}
|
||||||
|
|
||||||
void Gizmo::createAxisInstance(Gizmo::Axis axis)
|
void Gizmo::createAxisInstance(Gizmo::Axis axis)
|
||||||
{
|
{
|
||||||
auto &rm = _engine->getRenderableManager();
|
auto &rm = _engine->getRenderableManager();
|
||||||
@@ -52,7 +73,7 @@ namespace thermion
|
|||||||
TRACE("Created Gizmo axis glTF instance with head entity %d", instance->getEntity());
|
TRACE("Created Gizmo axis glTF instance with head entity %d", instance->getEntity());
|
||||||
|
|
||||||
materialInstance->setParameter("baseColorFactor", inactiveColors[axis]);
|
materialInstance->setParameter("baseColorFactor", inactiveColors[axis]);
|
||||||
materialInstance->setParameter("scale", 4.0f);
|
materialInstance->setParameter("scale", _scale);
|
||||||
|
|
||||||
auto hitTestEntity = instance->findEntityByName("HitTest");
|
auto hitTestEntity = instance->findEntityByName("HitTest");
|
||||||
TRACE("Created hit test entity %d for axis %d", hitTestEntity, axis);
|
TRACE("Created hit test entity %d for axis %d", hitTestEntity, axis);
|
||||||
@@ -73,8 +94,8 @@ namespace thermion
|
|||||||
{
|
{
|
||||||
auto *hitTestMaterialInstance = _material->createInstance();
|
auto *hitTestMaterialInstance = _material->createInstance();
|
||||||
_materialInstances.push_back(hitTestMaterialInstance);
|
_materialInstances.push_back(hitTestMaterialInstance);
|
||||||
hitTestMaterialInstance->setParameter("baseColorFactor", math::float4{1.0f, 0.0f, 1.0f, 0.5f});
|
hitTestMaterialInstance->setParameter("baseColorFactor", math::float4{0.0f, 0.0f, 0.0f, 0.0f});
|
||||||
hitTestMaterialInstance->setParameter("scale", 4.0f);
|
hitTestMaterialInstance->setParameter("scale", _scale);
|
||||||
rm.setMaterialInstanceAt(renderableInstance, 0, hitTestMaterialInstance);
|
rm.setMaterialInstanceAt(renderableInstance, 0, hitTestMaterialInstance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,7 +107,7 @@ namespace thermion
|
|||||||
auto &tm = _engine->getTransformManager();
|
auto &tm = _engine->getTransformManager();
|
||||||
auto transformInstance = tm.getInstance(instance->getEntity());
|
auto transformInstance = tm.getInstance(instance->getEntity());
|
||||||
tm.setTransform(transformInstance, transform);
|
tm.setTransform(transformInstance, transform);
|
||||||
|
|
||||||
// parent this entity's transform to the Gizmo _parent entity
|
// parent this entity's transform to the Gizmo _parent entity
|
||||||
tm.setParent(transformInstance, tm.getInstance(_parent));
|
tm.setParent(transformInstance, tm.getInstance(_parent));
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,8 @@
|
|||||||
#include "scene/GeometrySceneAssetBuilder.hpp"
|
#include "scene/GeometrySceneAssetBuilder.hpp"
|
||||||
#include "UnprojectTexture.hpp"
|
#include "UnprojectTexture.hpp"
|
||||||
|
|
||||||
#include "resources/gizmo_glb.h"
|
#include "resources/translation_gizmo_glb.h"
|
||||||
|
#include "resources/rotation_gizmo_glb.h"
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
@@ -135,7 +136,7 @@ namespace thermion
|
|||||||
_engine->destroy(_unlitFixedSizeMaterial);
|
_engine->destroy(_unlitFixedSizeMaterial);
|
||||||
_engine->destroy(_gizmoMaterial);
|
_engine->destroy(_gizmoMaterial);
|
||||||
_cameras.clear();
|
_cameras.clear();
|
||||||
|
|
||||||
_grid = nullptr;
|
_grid = nullptr;
|
||||||
|
|
||||||
_gltfResourceLoader->asyncCancelLoad();
|
_gltfResourceLoader->asyncCancelLoad();
|
||||||
@@ -152,37 +153,62 @@ namespace thermion
|
|||||||
AssetLoader::destroy(&_assetLoader);
|
AssetLoader::destroy(&_assetLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneAsset *SceneManager::createGrid() {
|
SceneAsset *SceneManager::createGrid()
|
||||||
if(!_grid) {
|
{
|
||||||
|
if (!_grid)
|
||||||
|
{
|
||||||
_grid = std::make_unique<GridOverlay>(*_engine);
|
_grid = std::make_unique<GridOverlay>(*_engine);
|
||||||
}
|
}
|
||||||
return _grid.get();
|
return _grid.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SceneManager::isGridEntity(utils::Entity entity) {
|
bool SceneManager::isGridEntity(utils::Entity entity)
|
||||||
if(!_grid) {
|
{
|
||||||
|
if (!_grid)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(entity == _grid->getEntity()) {
|
if (entity == _grid->getEntity())
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for(int i =0; i < _grid->getChildEntityCount(); i++) {
|
for (int i = 0; i < _grid->getChildEntityCount(); i++)
|
||||||
if(entity == _grid->getChildEntities()[i]) {
|
{
|
||||||
|
if (entity == _grid->getChildEntities()[i])
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Gizmo *SceneManager::createGizmo(View *view, Scene *scene)
|
Gizmo *SceneManager::createGizmo(View *view, Scene *scene, GizmoType type)
|
||||||
{
|
{
|
||||||
if(!_gizmoGlb) {
|
TRACE("Creating gizmo type %d", type);
|
||||||
_gizmoGlb = loadGlbFromBuffer(GIZMO_GLB_GIZMO_DATA, GIZMO_GLB_GIZMO_SIZE, 100, true, 4, 0, false, false);
|
Gizmo *raw;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case GizmoType::TRANSLATION:
|
||||||
|
if (!_translationGizmoGlb)
|
||||||
|
{
|
||||||
|
TRACE("Translation gizmo source not found, loading");
|
||||||
|
_translationGizmoGlb = loadGlbFromBuffer(TRANSLATION_GIZMO_GLB_TRANSLATION_GIZMO_DATA, TRANSLATION_GIZMO_GLB_TRANSLATION_GIZMO_SIZE, 100, true, 4, 0, false, false);
|
||||||
|
}
|
||||||
|
raw = new Gizmo(_translationGizmoGlb, _engine, view, scene, _unlitFixedSizeMaterial);
|
||||||
|
TRACE("Built translation gizmo");
|
||||||
|
break;
|
||||||
|
case GizmoType::ROTATION:
|
||||||
|
if (!_rotationGizmoGlb)
|
||||||
|
{
|
||||||
|
TRACE("Rotation gizmo source not found, loading");
|
||||||
|
_rotationGizmoGlb = loadGlbFromBuffer(ROTATION_GIZMO_GLB_ROTATION_GIZMO_DATA, ROTATION_GIZMO_GLB_ROTATION_GIZMO_SIZE, 100, true, 4, 0, false, false);
|
||||||
|
}
|
||||||
|
raw = new Gizmo(_rotationGizmoGlb, _engine, view, scene, _unlitFixedSizeMaterial);
|
||||||
|
TRACE("Built rotation gizmo");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
auto gizmo = std::make_unique<Gizmo>(_gizmoGlb, _engine, view, scene, _unlitFixedSizeMaterial);
|
|
||||||
auto *raw = gizmo.get();
|
_sceneAssets.push_back(std::unique_ptr<Gizmo>(raw));
|
||||||
_sceneAssets.push_back(std::move(gizmo));
|
|
||||||
|
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,8 +312,7 @@ namespace thermion
|
|||||||
asset,
|
asset,
|
||||||
_assetLoader,
|
_assetLoader,
|
||||||
_engine,
|
_engine,
|
||||||
_ncm
|
_ncm);
|
||||||
);
|
|
||||||
auto filamentInstance = asset->getInstance();
|
auto filamentInstance = asset->getInstance();
|
||||||
size_t entityCount = filamentInstance->getEntityCount();
|
size_t entityCount = filamentInstance->getEntityCount();
|
||||||
|
|
||||||
@@ -375,16 +400,16 @@ namespace thermion
|
|||||||
asset,
|
asset,
|
||||||
_assetLoader,
|
_assetLoader,
|
||||||
_engine,
|
_engine,
|
||||||
_ncm
|
_ncm);
|
||||||
);
|
|
||||||
|
|
||||||
auto sceneAssetInstance = sceneAsset->createInstance();
|
auto sceneAssetInstance = sceneAsset->createInstance();
|
||||||
if(addToScene) {
|
if (addToScene)
|
||||||
|
{
|
||||||
sceneAssetInstance->addAllEntities(_scene);
|
sceneAssetInstance->addAllEntities(_scene);
|
||||||
}
|
}
|
||||||
sceneAssetInstance->setPriority(_engine->getRenderableManager(), priority);
|
sceneAssetInstance->setPriority(_engine->getRenderableManager(), priority);
|
||||||
sceneAssetInstance->setLayer(_engine->getRenderableManager(), layer);
|
sceneAssetInstance->setLayer(_engine->getRenderableManager(), layer);
|
||||||
|
|
||||||
auto *raw = sceneAsset.get();
|
auto *raw = sceneAsset.get();
|
||||||
|
|
||||||
_sceneAssets.push_back(std::move(sceneAsset));
|
_sceneAssets.push_back(std::move(sceneAsset));
|
||||||
|
|||||||
Reference in New Issue
Block a user