feat: re-implement (native) Gizmo class, expose preserveScaling parameter for setParent, add methods for getting viewport bounding box from renderable entity
This commit is contained in:
@@ -4,10 +4,12 @@ headers:
|
|||||||
- '../native/include/ThermionDartFFIApi.h'
|
- '../native/include/ThermionDartFFIApi.h'
|
||||||
- '../native/include/ThermionDartApi.h'
|
- '../native/include/ThermionDartApi.h'
|
||||||
- '../native/include/ResourceBuffer.h'
|
- '../native/include/ResourceBuffer.h'
|
||||||
|
- '../native/include/Aabb2.h'
|
||||||
include-directives:
|
include-directives:
|
||||||
- '../native/include/ThermionDartFFIApi.h'
|
- '../native/include/ThermionDartFFIApi.h'
|
||||||
- '../native/include/ThermionDartApi.h'
|
- '../native/include/ThermionDartApi.h'
|
||||||
- '../native/include/ResourceBuffer.h'
|
- '../native/include/ResourceBuffer.h'
|
||||||
|
- '../native/include/Aabb2.h'
|
||||||
ffi-native:
|
ffi-native:
|
||||||
assetId: package:thermion_dart/thermion_dart.dart
|
assetId: package:thermion_dart/thermion_dart.dart
|
||||||
ignore-source-errors: true
|
ignore-source-errors: true
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ external void remove_ibl(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Int Function(
|
EntityId Function(
|
||||||
ffi.Pointer<ffi.Void>,
|
ffi.Pointer<ffi.Void>,
|
||||||
ffi.Uint8,
|
ffi.Uint8,
|
||||||
ffi.Float,
|
ffi.Float,
|
||||||
@@ -161,7 +161,7 @@ external int add_light(
|
|||||||
bool shadows,
|
bool shadows,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int)>()
|
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId)>()
|
||||||
external void remove_light(
|
external void remove_light(
|
||||||
ffi.Pointer<ffi.Void> viewer,
|
ffi.Pointer<ffi.Void> viewer,
|
||||||
int entityId,
|
int entityId,
|
||||||
@@ -173,7 +173,7 @@ external void clear_lights(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Char>, ffi.Int)>()
|
EntityId Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Char>, ffi.Int)>()
|
||||||
external int load_glb(
|
external int load_glb(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
ffi.Pointer<ffi.Char> assetPath,
|
ffi.Pointer<ffi.Char> assetPath,
|
||||||
@@ -181,7 +181,7 @@ external int load_glb(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>, ffi.Size)>()
|
EntityId Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>, ffi.Size)>()
|
||||||
external int load_glb_from_buffer(
|
external int load_glb_from_buffer(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
ffi.Pointer<ffi.Void> data,
|
ffi.Pointer<ffi.Void> data,
|
||||||
@@ -189,7 +189,7 @@ external int load_glb_from_buffer(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Int Function(
|
EntityId Function(
|
||||||
ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>)>()
|
ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>)>()
|
||||||
external int load_gltf(
|
external int load_gltf(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
@@ -197,24 +197,24 @@ external int load_gltf(
|
|||||||
ffi.Pointer<ffi.Char> relativePath,
|
ffi.Pointer<ffi.Char> relativePath,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Int)>()
|
@ffi.Native<EntityId Function(ffi.Pointer<ffi.Void>, EntityId)>()
|
||||||
external int create_instance(
|
external int create_instance(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int id,
|
int id,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Int)>()
|
@ffi.Native<ffi.Int Function(ffi.Pointer<ffi.Void>, EntityId)>()
|
||||||
external int get_instance_count(
|
external int get_instance_count(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entityId,
|
int entityId,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Pointer<ffi.Int>)>()
|
ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Pointer<EntityId>)>()
|
||||||
external void get_instances(
|
external void get_instances(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entityId,
|
int entityId,
|
||||||
ffi.Pointer<ffi.Int> out,
|
ffi.Pointer<EntityId> out,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>)>()
|
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>)>()
|
||||||
@@ -222,13 +222,13 @@ external void set_main_camera(
|
|||||||
ffi.Pointer<ffi.Void> viewer,
|
ffi.Pointer<ffi.Void> viewer,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Int Function(ffi.Pointer<ffi.Void>)>()
|
@ffi.Native<EntityId Function(ffi.Pointer<ffi.Void>)>()
|
||||||
external int get_main_camera(
|
external int get_main_camera(
|
||||||
ffi.Pointer<ffi.Void> viewer,
|
ffi.Pointer<ffi.Void> viewer,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Bool Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Pointer<ffi.Char>)>()
|
ffi.Bool Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Pointer<ffi.Char>)>()
|
||||||
external bool set_camera(
|
external bool set_camera(
|
||||||
ffi.Pointer<ffi.Void> viewer,
|
ffi.Pointer<ffi.Void> viewer,
|
||||||
int entity,
|
int entity,
|
||||||
@@ -263,6 +263,15 @@ external void render(
|
|||||||
ffi.Pointer<ffi.Void> data,
|
ffi.Pointer<ffi.Void> data,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Uint8>,
|
||||||
|
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>>)>()
|
||||||
|
external void capture(
|
||||||
|
ffi.Pointer<ffi.Void> viewer,
|
||||||
|
ffi.Pointer<ffi.Uint8> pixelBuffer,
|
||||||
|
ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> callback,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(
|
ffi.Void Function(
|
||||||
ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>, ffi.Uint32, ffi.Uint32)>()
|
ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>, ffi.Uint32, ffi.Uint32)>()
|
||||||
@@ -335,7 +344,7 @@ external void grab_end(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Pointer<ffi.Char>,
|
ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Pointer<ffi.Char>,
|
||||||
ffi.Pointer<ffi.Float>, ffi.Int)>()
|
ffi.Pointer<ffi.Float>, ffi.Int)>()
|
||||||
external void apply_weights(
|
external void apply_weights(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
@@ -347,7 +356,7 @@ external void apply_weights(
|
|||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Bool Function(
|
ffi.Bool Function(
|
||||||
ffi.Pointer<ffi.Void>, ffi.Int, ffi.Pointer<ffi.Float>, ffi.Int)>()
|
ffi.Pointer<ffi.Void>, EntityId, ffi.Pointer<ffi.Float>, ffi.Int)>()
|
||||||
external bool set_morph_target_weights(
|
external bool set_morph_target_weights(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entity,
|
int entity,
|
||||||
@@ -356,7 +365,7 @@ external bool set_morph_target_weights(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Bool Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Pointer<ffi.Float>,
|
ffi.Bool Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Pointer<ffi.Float>,
|
||||||
ffi.Pointer<ffi.Int>, ffi.Int, ffi.Int, ffi.Float)>()
|
ffi.Pointer<ffi.Int>, ffi.Int, ffi.Int, ffi.Float)>()
|
||||||
external bool set_morph_animation(
|
external bool set_morph_animation(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
@@ -368,13 +377,13 @@ external bool set_morph_animation(
|
|||||||
double frameLengthInMs,
|
double frameLengthInMs,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int)>()
|
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId)>()
|
||||||
external void clear_morph_animation(
|
external void clear_morph_animation(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entity,
|
int entity,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int)>()
|
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId)>()
|
||||||
external void reset_to_rest_pose(
|
external void reset_to_rest_pose(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int asset,
|
int asset,
|
||||||
@@ -383,7 +392,7 @@ external void reset_to_rest_pose(
|
|||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(
|
ffi.Void Function(
|
||||||
ffi.Pointer<ffi.Void>,
|
ffi.Pointer<ffi.Void>,
|
||||||
ffi.Int,
|
EntityId,
|
||||||
ffi.Int,
|
ffi.Int,
|
||||||
ffi.Int,
|
ffi.Int,
|
||||||
ffi.Pointer<ffi.Float>,
|
ffi.Pointer<ffi.Float>,
|
||||||
@@ -406,7 +415,8 @@ external void add_bone_animation(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Pointer<ffi.Float>)>()
|
ffi.Void Function(
|
||||||
|
ffi.Pointer<ffi.Void>, EntityId, ffi.Pointer<ffi.Float>)>()
|
||||||
external void get_local_transform(
|
external void get_local_transform(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entityId,
|
int entityId,
|
||||||
@@ -414,7 +424,7 @@ external void get_local_transform(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Int,
|
ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Int,
|
||||||
ffi.Pointer<ffi.Float>, ffi.Int)>()
|
ffi.Pointer<ffi.Float>, ffi.Int)>()
|
||||||
external void get_rest_local_transforms(
|
external void get_rest_local_transforms(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
@@ -425,7 +435,8 @@ external void get_rest_local_transforms(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Pointer<ffi.Float>)>()
|
ffi.Void Function(
|
||||||
|
ffi.Pointer<ffi.Void>, EntityId, ffi.Pointer<ffi.Float>)>()
|
||||||
external void get_world_transform(
|
external void get_world_transform(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entityId,
|
int entityId,
|
||||||
@@ -433,7 +444,7 @@ external void get_world_transform(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Int, ffi.Int,
|
ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Int, ffi.Int,
|
||||||
ffi.Pointer<ffi.Float>)>()
|
ffi.Pointer<ffi.Float>)>()
|
||||||
external void get_inverse_bind_matrix(
|
external void get_inverse_bind_matrix(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
@@ -444,7 +455,7 @@ external void get_inverse_bind_matrix(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Bool Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Int, ffi.Int,
|
ffi.Bool Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Int, ffi.Int,
|
||||||
ffi.Pointer<ffi.Float>)>()
|
ffi.Pointer<ffi.Float>)>()
|
||||||
external bool set_bone_transform(
|
external bool set_bone_transform(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
@@ -455,7 +466,7 @@ external bool set_bone_transform(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Int, ffi.Bool,
|
ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Int, ffi.Bool,
|
||||||
ffi.Bool, ffi.Bool, ffi.Float, ffi.Float)>()
|
ffi.Bool, ffi.Bool, ffi.Float, ffi.Float)>()
|
||||||
external void play_animation(
|
external void play_animation(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
@@ -469,7 +480,7 @@ external void play_animation(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Int, ffi.Int)>()
|
ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Int, ffi.Int)>()
|
||||||
external void set_animation_frame(
|
external void set_animation_frame(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entity,
|
int entity,
|
||||||
@@ -477,14 +488,14 @@ external void set_animation_frame(
|
|||||||
int animationFrame,
|
int animationFrame,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Int)>()
|
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Int)>()
|
||||||
external void stop_animation(
|
external void stop_animation(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entity,
|
int entity,
|
||||||
int index,
|
int index,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Int)>()
|
@ffi.Native<ffi.Int Function(ffi.Pointer<ffi.Void>, EntityId)>()
|
||||||
external int get_animation_count(
|
external int get_animation_count(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int asset,
|
int asset,
|
||||||
@@ -492,7 +503,7 @@ external int get_animation_count(
|
|||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(
|
ffi.Void Function(
|
||||||
ffi.Pointer<ffi.Void>, ffi.Int, ffi.Pointer<ffi.Char>, ffi.Int)>()
|
ffi.Pointer<ffi.Void>, EntityId, ffi.Pointer<ffi.Char>, ffi.Int)>()
|
||||||
external void get_animation_name(
|
external void get_animation_name(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entity,
|
int entity,
|
||||||
@@ -500,14 +511,14 @@ external void get_animation_name(
|
|||||||
int index,
|
int index,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Float Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Int)>()
|
@ffi.Native<ffi.Float Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Int)>()
|
||||||
external double get_animation_duration(
|
external double get_animation_duration(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entity,
|
int entity,
|
||||||
int index,
|
int index,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Int)>()
|
@ffi.Native<ffi.Int Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Int)>()
|
||||||
external int get_bone_count(
|
external int get_bone_count(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int assetEntity,
|
int assetEntity,
|
||||||
@@ -515,7 +526,7 @@ external int get_bone_count(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int,
|
ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId,
|
||||||
ffi.Pointer<ffi.Pointer<ffi.Char>>, ffi.Int)>()
|
ffi.Pointer<ffi.Pointer<ffi.Char>>, ffi.Int)>()
|
||||||
external void get_bone_names(
|
external void get_bone_names(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
@@ -525,7 +536,7 @@ external void get_bone_names(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Int, ffi.Int)>()
|
EntityId Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Int, ffi.Int)>()
|
||||||
external int get_bone(
|
external int get_bone(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entityId,
|
int entityId,
|
||||||
@@ -534,21 +545,22 @@ external int get_bone(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Bool Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Pointer<ffi.Float>)>()
|
ffi.Bool Function(
|
||||||
|
ffi.Pointer<ffi.Void>, EntityId, ffi.Pointer<ffi.Float>)>()
|
||||||
external bool set_transform(
|
external bool set_transform(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entityId,
|
int entityId,
|
||||||
ffi.Pointer<ffi.Float> transform,
|
ffi.Pointer<ffi.Float> transform,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Bool Function(ffi.Pointer<ffi.Void>, ffi.Int)>()
|
@ffi.Native<ffi.Bool Function(ffi.Pointer<ffi.Void>, EntityId)>()
|
||||||
external bool update_bone_matrices(
|
external bool update_bone_matrices(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entityId,
|
int entityId,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Int,
|
ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, EntityId,
|
||||||
ffi.Pointer<ffi.Char>, ffi.Int)>()
|
ffi.Pointer<ffi.Char>, ffi.Int)>()
|
||||||
external void get_morph_target_name(
|
external void get_morph_target_name(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
@@ -558,14 +570,14 @@ external void get_morph_target_name(
|
|||||||
int index,
|
int index,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Int)>()
|
@ffi.Native<ffi.Int Function(ffi.Pointer<ffi.Void>, EntityId, EntityId)>()
|
||||||
external int get_morph_target_name_count(
|
external int get_morph_target_name_count(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int assetEntity,
|
int assetEntity,
|
||||||
int childEntity,
|
int childEntity,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int)>()
|
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId)>()
|
||||||
external void remove_entity(
|
external void remove_entity(
|
||||||
ffi.Pointer<ffi.Void> viewer,
|
ffi.Pointer<ffi.Void> viewer,
|
||||||
int asset,
|
int asset,
|
||||||
@@ -577,7 +589,7 @@ external void clear_entities(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Bool Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Pointer<ffi.Char>,
|
ffi.Bool Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Pointer<ffi.Char>,
|
||||||
ffi.Int, ffi.Float, ffi.Float, ffi.Float, ffi.Float)>()
|
ffi.Int, ffi.Float, ffi.Float, ffi.Float, ffi.Float)>()
|
||||||
external bool set_material_color(
|
external bool set_material_color(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
@@ -590,14 +602,14 @@ external bool set_material_color(
|
|||||||
double a,
|
double a,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int)>()
|
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId)>()
|
||||||
external void transform_to_unit_cube(
|
external void transform_to_unit_cube(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int asset,
|
int asset,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Float, ffi.Float,
|
ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Float, ffi.Float,
|
||||||
ffi.Float, ffi.Bool)>()
|
ffi.Float, ffi.Bool)>()
|
||||||
external void queue_position_update(
|
external void queue_position_update(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
@@ -609,7 +621,7 @@ external void queue_position_update(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Float, ffi.Float,
|
ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Float, ffi.Float,
|
||||||
ffi.Float, ffi.Float, ffi.Float, ffi.Bool)>()
|
ffi.Float, ffi.Float, ffi.Float, ffi.Bool)>()
|
||||||
external void queue_rotation_update(
|
external void queue_rotation_update(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
@@ -624,7 +636,7 @@ external void queue_rotation_update(
|
|||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(
|
ffi.Void Function(
|
||||||
ffi.Pointer<ffi.Void>, ffi.Int, ffi.Float, ffi.Float, ffi.Float)>()
|
ffi.Pointer<ffi.Void>, EntityId, ffi.Float, ffi.Float, ffi.Float)>()
|
||||||
external void set_position(
|
external void set_position(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entity,
|
int entity,
|
||||||
@@ -634,7 +646,7 @@ external void set_position(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Float, ffi.Float,
|
ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Float, ffi.Float,
|
||||||
ffi.Float, ffi.Float, ffi.Float)>()
|
ffi.Float, ffi.Float, ffi.Float)>()
|
||||||
external void set_rotation(
|
external void set_rotation(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
@@ -646,14 +658,14 @@ external void set_rotation(
|
|||||||
double w,
|
double w,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Float)>()
|
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Float)>()
|
||||||
external void set_scale(
|
external void set_scale(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entity,
|
int entity,
|
||||||
double scale,
|
double scale,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int)>()
|
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId)>()
|
||||||
external void move_camera_to_asset(
|
external void move_camera_to_asset(
|
||||||
ffi.Pointer<ffi.Void> viewer,
|
ffi.Pointer<ffi.Void> viewer,
|
||||||
int asset,
|
int asset,
|
||||||
@@ -782,7 +794,7 @@ external void set_camera_manipulator_options(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Pointer<ffi.Char>)>()
|
ffi.Int Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Pointer<ffi.Char>)>()
|
||||||
external int hide_mesh(
|
external int hide_mesh(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entity,
|
int entity,
|
||||||
@@ -790,7 +802,7 @@ external int hide_mesh(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Pointer<ffi.Char>)>()
|
ffi.Int Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Pointer<ffi.Char>)>()
|
||||||
external int reveal_mesh(
|
external int reveal_mesh(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entity,
|
int entity,
|
||||||
@@ -838,32 +850,32 @@ external void set_antialiasing(
|
|||||||
ffi.Int,
|
ffi.Int,
|
||||||
ffi.Pointer<
|
ffi.Pointer<
|
||||||
ffi.NativeFunction<
|
ffi.NativeFunction<
|
||||||
ffi.Void Function(ffi.Int entityId, ffi.Int x, ffi.Int y)>>)>()
|
ffi.Void Function(EntityId entityId, ffi.Int x, ffi.Int y)>>)>()
|
||||||
external void filament_pick(
|
external void filament_pick(
|
||||||
ffi.Pointer<ffi.Void> viewer,
|
ffi.Pointer<ffi.Void> viewer,
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
ffi.Pointer<
|
ffi.Pointer<
|
||||||
ffi.NativeFunction<
|
ffi.NativeFunction<
|
||||||
ffi.Void Function(ffi.Int entityId, ffi.Int x, ffi.Int y)>>
|
ffi.Void Function(EntityId entityId, ffi.Int x, ffi.Int y)>>
|
||||||
callback,
|
callback,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Void>, ffi.Int)>()
|
@ffi.Native<ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Void>, EntityId)>()
|
||||||
external ffi.Pointer<ffi.Char> get_name_for_entity(
|
external ffi.Pointer<ffi.Char> get_name_for_entity(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entityId,
|
int entityId,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Pointer<ffi.Char>)>()
|
EntityId Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Pointer<ffi.Char>)>()
|
||||||
external int find_child_entity_by_name(
|
external int find_child_entity_by_name(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int parent,
|
int parent,
|
||||||
ffi.Pointer<ffi.Char> name,
|
ffi.Pointer<ffi.Char> name,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Bool)>()
|
@ffi.Native<ffi.Int Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Bool)>()
|
||||||
external int get_entity_count(
|
external int get_entity_count(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int target,
|
int target,
|
||||||
@@ -872,17 +884,17 @@ external int get_entity_count(
|
|||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(
|
ffi.Void Function(
|
||||||
ffi.Pointer<ffi.Void>, ffi.Int, ffi.Bool, ffi.Pointer<ffi.Int>)>()
|
ffi.Pointer<ffi.Void>, EntityId, ffi.Bool, ffi.Pointer<EntityId>)>()
|
||||||
external void get_entities(
|
external void get_entities(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int target,
|
int target,
|
||||||
bool renderableOnly,
|
bool renderableOnly,
|
||||||
ffi.Pointer<ffi.Int> out,
|
ffi.Pointer<EntityId> out,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Pointer<ffi.Char> Function(
|
ffi.Pointer<ffi.Char> Function(
|
||||||
ffi.Pointer<ffi.Void>, ffi.Int, ffi.Int, ffi.Bool)>()
|
ffi.Pointer<ffi.Void>, EntityId, ffi.Int, ffi.Bool)>()
|
||||||
external ffi.Pointer<ffi.Char> get_entity_name_at(
|
external ffi.Pointer<ffi.Char> get_entity_name_at(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int target,
|
int target,
|
||||||
@@ -913,41 +925,41 @@ external void thermion_flutter_free(
|
|||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(
|
ffi.Void Function(
|
||||||
ffi.Pointer<ffi.Void>,
|
ffi.Pointer<ffi.Void>,
|
||||||
ffi.Int,
|
EntityId,
|
||||||
ffi.Pointer<
|
ffi.Pointer<
|
||||||
ffi.NativeFunction<
|
ffi.NativeFunction<
|
||||||
ffi.Void Function(ffi.Int entityId1, ffi.Int entityId2)>>,
|
ffi.Void Function(EntityId entityId1, EntityId entityId2)>>,
|
||||||
ffi.Bool)>()
|
ffi.Bool)>()
|
||||||
external void add_collision_component(
|
external void add_collision_component(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entityId,
|
int entityId,
|
||||||
ffi.Pointer<
|
ffi.Pointer<
|
||||||
ffi.NativeFunction<
|
ffi.NativeFunction<
|
||||||
ffi.Void Function(ffi.Int entityId1, ffi.Int entityId2)>>
|
ffi.Void Function(EntityId entityId1, EntityId entityId2)>>
|
||||||
callback,
|
callback,
|
||||||
bool affectsCollidingTransform,
|
bool affectsCollidingTransform,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int)>()
|
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId)>()
|
||||||
external void remove_collision_component(
|
external void remove_collision_component(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entityId,
|
int entityId,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Bool Function(ffi.Pointer<ffi.Void>, ffi.Int)>()
|
@ffi.Native<ffi.Bool Function(ffi.Pointer<ffi.Void>, EntityId)>()
|
||||||
external bool add_animation_component(
|
external bool add_animation_component(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entityId,
|
int entityId,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int)>()
|
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId)>()
|
||||||
external void remove_animation_component(
|
external void remove_animation_component(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entityId,
|
int entityId,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Float>, ffi.Int,
|
EntityId Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Float>, ffi.Int,
|
||||||
ffi.Pointer<ffi.Uint16>, ffi.Int, ffi.Int, ffi.Pointer<ffi.Char>)>()
|
ffi.Pointer<ffi.Uint16>, ffi.Int, ffi.Int, ffi.Pointer<ffi.Char>)>()
|
||||||
external int create_geometry(
|
external int create_geometry(
|
||||||
ffi.Pointer<ffi.Void> viewer,
|
ffi.Pointer<ffi.Void> viewer,
|
||||||
@@ -959,36 +971,44 @@ external int create_geometry(
|
|||||||
ffi.Pointer<ffi.Char> materialPath,
|
ffi.Pointer<ffi.Char> materialPath,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Int Function(ffi.Pointer<ffi.Void>, ffi.Int)>()
|
@ffi.Native<EntityId Function(ffi.Pointer<ffi.Void>, EntityId)>()
|
||||||
external int get_parent(
|
external int get_parent(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int child,
|
int child,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Int)>()
|
@ffi.Native<
|
||||||
|
ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, EntityId, ffi.Bool)>()
|
||||||
external void set_parent(
|
external void set_parent(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int child,
|
int child,
|
||||||
int parent,
|
int parent,
|
||||||
|
bool preserveScaling,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int)>()
|
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId)>()
|
||||||
external void test_collisions(
|
external void test_collisions(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entity,
|
int entity,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Int, ffi.Int)>()
|
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Int)>()
|
||||||
external void set_priority(
|
external void set_priority(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
int entityId,
|
int entityId,
|
||||||
int priority,
|
int priority,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Int>)>()
|
@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>, ffi.Pointer<EntityId>)>()
|
||||||
external void get_gizmo(
|
external void get_gizmo(
|
||||||
ffi.Pointer<ffi.Void> sceneManager,
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
ffi.Pointer<ffi.Int> out,
|
ffi.Pointer<EntityId> out,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<Aabb2 Function(ffi.Pointer<ffi.Void>, EntityId)>()
|
||||||
|
external Aabb2 get_bounding_box(
|
||||||
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
|
int entity,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
@@ -1499,6 +1519,27 @@ typedef LoadFilamentResourceIntoOutPointerFunction = ffi.Void Function(
|
|||||||
ffi.Pointer<ffi.Char> uri, ffi.Pointer<ResourceBuffer> out);
|
ffi.Pointer<ffi.Char> uri, ffi.Pointer<ResourceBuffer> out);
|
||||||
typedef DartLoadFilamentResourceIntoOutPointerFunction = void Function(
|
typedef DartLoadFilamentResourceIntoOutPointerFunction = void Function(
|
||||||
ffi.Pointer<ffi.Char> uri, ffi.Pointer<ResourceBuffer> out);
|
ffi.Pointer<ffi.Char> uri, ffi.Pointer<ResourceBuffer> out);
|
||||||
|
|
||||||
|
final class Aabb2 extends ffi.Struct {
|
||||||
|
@ffi.Float()
|
||||||
|
external double minX;
|
||||||
|
|
||||||
|
@ffi.Float()
|
||||||
|
external double minY;
|
||||||
|
|
||||||
|
@ffi.Float()
|
||||||
|
external double maxX;
|
||||||
|
|
||||||
|
@ffi.Float()
|
||||||
|
external double maxY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This header replicates most of the methods in ThermionDartApi.h.
|
||||||
|
/// It represents the interface for:
|
||||||
|
/// - invoking those methods that must be called on the main Filament engine thread
|
||||||
|
/// - setting up a render loop
|
||||||
|
typedef EntityId = ffi.Int32;
|
||||||
|
typedef DartEntityId = int;
|
||||||
typedef _ManipulatorMode = ffi.Int32;
|
typedef _ManipulatorMode = ffi.Int32;
|
||||||
typedef Dart_ManipulatorMode = int;
|
typedef Dart_ManipulatorMode = int;
|
||||||
typedef FilamentRenderCallback
|
typedef FilamentRenderCallback
|
||||||
@@ -1508,13 +1549,6 @@ typedef FilamentRenderCallbackFunction = ffi.Void Function(
|
|||||||
typedef DartFilamentRenderCallbackFunction = void Function(
|
typedef DartFilamentRenderCallbackFunction = void Function(
|
||||||
ffi.Pointer<ffi.Void> owner);
|
ffi.Pointer<ffi.Void> owner);
|
||||||
|
|
||||||
/// This header replicates most of the methods in ThermionDartApi.h.
|
|
||||||
/// It represents the interface for:
|
|
||||||
/// - invoking those methods that must be called on the main Filament engine thread
|
|
||||||
/// - setting up a render loop
|
|
||||||
typedef EntityId = ffi.Int32;
|
|
||||||
typedef DartEntityId = int;
|
|
||||||
|
|
||||||
const int __bool_true_false_are_defined = 1;
|
const int __bool_true_false_are_defined = 1;
|
||||||
|
|
||||||
const int true1 = 1;
|
const int true1 = 1;
|
||||||
|
|||||||
@@ -1,3 +1,23 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
|
||||||
|
import 'package:vector_math/vector_math_64.dart';
|
||||||
|
|
||||||
|
abstract class AbstractGizmo {
|
||||||
|
bool get isActive;
|
||||||
|
|
||||||
|
void translate(double transX, double transY);
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
void attach(ThermionEntity entity);
|
||||||
|
|
||||||
|
void detach();
|
||||||
|
|
||||||
|
Aabb2 boundingBox = Aabb2();
|
||||||
|
|
||||||
|
void checkHover(double x, double y) {
|
||||||
|
if(boundingBox.containsVector2(Vector2(x, y)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
|
import 'dart:ffi';
|
||||||
|
|
||||||
|
import 'package:ffi/ffi.dart';
|
||||||
|
import 'package:thermion_dart/thermion_dart/entities/abstract_gizmo.dart';
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
import 'package:vector_math/vector_math_64.dart';
|
||||||
import '../thermion_viewer.dart';
|
import '../thermion_viewer.dart';
|
||||||
|
|
||||||
class Gizmo extends AbstractGizmo {
|
class Gizmo extends AbstractGizmo {
|
||||||
final ThermionEntity x;
|
final ThermionEntity x;
|
||||||
Vector3 _x = Vector3(0.1, 0, 0);
|
|
||||||
final ThermionEntity y;
|
final ThermionEntity y;
|
||||||
Vector3 _y = Vector3(0.0, 0.1, 0);
|
|
||||||
final ThermionEntity z;
|
final ThermionEntity z;
|
||||||
Vector3 _z = Vector3(0.0, 0.0, 0.1);
|
|
||||||
|
|
||||||
final ThermionViewer controller;
|
final ThermionEntity center;
|
||||||
|
|
||||||
|
final ThermionViewer _viewer;
|
||||||
|
|
||||||
ThermionEntity? _activeAxis;
|
ThermionEntity? _activeAxis;
|
||||||
ThermionEntity? _activeEntity;
|
ThermionEntity? _activeEntity;
|
||||||
@@ -18,29 +20,41 @@ class Gizmo extends AbstractGizmo {
|
|||||||
|
|
||||||
final Set<ThermionEntity> ignore;
|
final Set<ThermionEntity> ignore;
|
||||||
|
|
||||||
Gizmo(this.x, this.y, this.z, this.controller,
|
Aabb2 boundingBox = Aabb2();
|
||||||
|
|
||||||
|
Gizmo(this.x, this.y, this.z, this.center, this._viewer,
|
||||||
{this.ignore = const <ThermionEntity>{}}) {
|
{this.ignore = const <ThermionEntity>{}}) {
|
||||||
controller.pickResult.listen(_onPickResult);
|
_viewer.pickResult.listen(_onPickResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _reveal() async {
|
Future _reveal() async {
|
||||||
await controller.reveal(x, null);
|
await _viewer.reveal(x, null);
|
||||||
await controller.reveal(y, null);
|
await _viewer.reveal(y, null);
|
||||||
await controller.reveal(z, null);
|
await _viewer.reveal(z, null);
|
||||||
|
await _viewer.reveal(center, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final _stopwatch = Stopwatch();
|
||||||
|
|
||||||
|
var _translation = Vector3.zero();
|
||||||
|
|
||||||
void translate(double transX, double transY) async {
|
void translate(double transX, double transY) async {
|
||||||
late Vector3 vec;
|
if (!_stopwatch.isRunning) {
|
||||||
if (_activeAxis == x) {
|
_stopwatch.start();
|
||||||
vec = _x;
|
}
|
||||||
} else if (_activeAxis == y) {
|
if (_activeAxis == x) {
|
||||||
vec = _y;
|
_translation += Vector3(transX, 0.0, 0.0);
|
||||||
} else if (_activeAxis == z) {
|
} else {
|
||||||
vec = _z;
|
_translation += Vector3(0.0, transY, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_stopwatch.elapsedMilliseconds > 16) {
|
||||||
|
await _viewer.queuePositionUpdate(
|
||||||
|
_activeEntity!, _translation.x, _translation.y, _translation.z,
|
||||||
|
relative: true);
|
||||||
|
_stopwatch.reset();
|
||||||
|
_translation = Vector3.zero();
|
||||||
}
|
}
|
||||||
await controller.queuePositionUpdate(
|
|
||||||
_activeEntity!, transX * vec.x, -transY * vec.y, -transX * vec.z,
|
|
||||||
relative: true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
@@ -63,17 +77,22 @@ class Gizmo extends AbstractGizmo {
|
|||||||
_activeAxis = null;
|
_activeAxis = null;
|
||||||
_activeEntity = entity;
|
_activeEntity = entity;
|
||||||
await _reveal();
|
await _reveal();
|
||||||
await controller.setParent(x, entity);
|
|
||||||
await controller.setParent(y, entity);
|
await _viewer.setParent(x, entity);
|
||||||
await controller.setParent(z, entity);
|
await _viewer.setParent(y, entity);
|
||||||
|
await _viewer.setParent(z, entity);
|
||||||
|
await _viewer.setParent(center, entity);
|
||||||
|
boundingBox = await _viewer.getBoundingBox(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void detach() async {
|
void detach() async {
|
||||||
await controller.setParent(x, 0);
|
await _viewer.setParent(x, 0);
|
||||||
await controller.setParent(y, 0);
|
await _viewer.setParent(y, 0);
|
||||||
await controller.setParent(z, 0);
|
await _viewer.setParent(z, 0);
|
||||||
await controller.hide(x, null);
|
await _viewer.setParent(center, 0);
|
||||||
await controller.hide(y, null);
|
await _viewer.hide(x, null);
|
||||||
await controller.hide(z, null);
|
await _viewer.hide(y, null);
|
||||||
|
await _viewer.hide(z, null);
|
||||||
|
await _viewer.hide(center, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:thermion_dart/thermion_dart/entities/abstract_gizmo.dart';
|
||||||
import 'package:thermion_dart/thermion_dart/scene.dart';
|
import 'package:thermion_dart/thermion_dart/scene.dart';
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
import 'package:vector_math/vector_math_64.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
@@ -55,7 +56,6 @@ class TextureDetails {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract class ThermionViewer {
|
abstract class ThermionViewer {
|
||||||
|
|
||||||
Future<bool> get initialized;
|
Future<bool> get initialized;
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -719,7 +719,7 @@ abstract class ThermionViewer {
|
|||||||
///
|
///
|
||||||
/// Sets the parent transform of [child] to [parent].
|
/// Sets the parent transform of [child] to [parent].
|
||||||
///
|
///
|
||||||
Future setParent(ThermionEntity child, ThermionEntity parent);
|
Future setParent(ThermionEntity child, ThermionEntity parent, { bool preserveScaling });
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Test all collidable entities against this entity to see if any have collided.
|
/// Test all collidable entities against this entity to see if any have collided.
|
||||||
@@ -738,7 +738,7 @@ abstract class ThermionViewer {
|
|||||||
Scene get scene;
|
Scene get scene;
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
/// The gizmo for translating/rotating objects. Only one gizmo is present in the scene.
|
||||||
///
|
///
|
||||||
AbstractGizmo? get gizmo;
|
AbstractGizmo? get gizmo;
|
||||||
|
|
||||||
@@ -746,16 +746,10 @@ abstract class ThermionViewer {
|
|||||||
/// Register a callback to be invoked when this viewer is disposed.
|
/// Register a callback to be invoked when this viewer is disposed.
|
||||||
///
|
///
|
||||||
void onDispose(Future Function() callback);
|
void onDispose(Future Function() callback);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Gets the 2D bounding box (in viewport coordinates) for the given entity.
|
||||||
|
///
|
||||||
|
Future<Aabb2> getBoundingBox(ThermionEntity entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class AbstractGizmo {
|
|
||||||
bool get isActive;
|
|
||||||
|
|
||||||
void translate(double transX, double transY);
|
|
||||||
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
void attach(ThermionEntity entity);
|
|
||||||
|
|
||||||
void detach();
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import 'package:thermion_dart/thermion_dart/compatibility/compatibility.dart';
|
|||||||
import 'package:thermion_dart/thermion_dart/entities/gizmo.dart';
|
import 'package:thermion_dart/thermion_dart/entities/gizmo.dart';
|
||||||
import 'package:thermion_dart/thermion_dart/scene.dart';
|
import 'package:thermion_dart/thermion_dart/scene.dart';
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
import 'package:vector_math/vector_math_64.dart';
|
||||||
|
import 'package:vector_math/vector_math_64.dart' as v64;
|
||||||
import 'thermion_viewer.dart';
|
import 'thermion_viewer.dart';
|
||||||
import 'scene_impl.dart';
|
import 'scene_impl.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
@@ -67,9 +68,9 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
this._driver = driver ?? nullptr;
|
this._driver = driver ?? nullptr;
|
||||||
this._sharedContext = sharedContext ?? nullptr;
|
this._sharedContext = sharedContext ?? nullptr;
|
||||||
try {
|
try {
|
||||||
_onPickResultCallable =
|
_onPickResultCallable = NativeCallable<
|
||||||
NativeCallable<Void Function(Int entityId, Int x, Int y)>.listener(
|
Void Function(
|
||||||
_onPickResult);
|
EntityId entityId, Int x, Int y)>.listener(_onPickResult);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
_logger.severe(
|
_logger.severe(
|
||||||
"Failed to set pick result callback. This is expected if running on web/wasm");
|
"Failed to set pick result callback. This is expected if running on web/wasm");
|
||||||
@@ -127,9 +128,9 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
|
|
||||||
await setCameraManipulatorOptions(zoomSpeed: 1.0);
|
await setCameraManipulatorOptions(zoomSpeed: 1.0);
|
||||||
|
|
||||||
final out = allocator<Int>(3);
|
final out = allocator<EntityId>(4);
|
||||||
get_gizmo(_sceneManager!, out);
|
get_gizmo(_sceneManager!, out);
|
||||||
_gizmo = Gizmo(out[0], out[1], out[2], this);
|
_gizmo = Gizmo(out[0], out[1], out[2], out[3], this);
|
||||||
allocator.free(out);
|
allocator.free(out);
|
||||||
|
|
||||||
this._initialized.complete(true);
|
this._initialized.complete(true);
|
||||||
@@ -408,7 +409,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
@override
|
@override
|
||||||
Future<List<ThermionEntity>> getInstances(ThermionEntity entity) async {
|
Future<List<ThermionEntity>> getInstances(ThermionEntity entity) async {
|
||||||
var count = await getInstanceCount(entity);
|
var count = await getInstanceCount(entity);
|
||||||
var out = allocator<Int>(count);
|
var out = allocator<Int32>(count);
|
||||||
get_instances(_sceneManager!, entity, out);
|
get_instances(_sceneManager!, entity, out);
|
||||||
var instances = <ThermionEntity>[];
|
var instances = <ThermionEntity>[];
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
@@ -1364,7 +1365,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
_scene!.registerSelected(entityId);
|
_scene!.registerSelected(entityId);
|
||||||
}
|
}
|
||||||
|
|
||||||
late NativeCallable<Void Function(Int entityId, Int x, Int y)>
|
late NativeCallable<Void Function(EntityId entityId, Int x, Int y)>
|
||||||
_onPickResultCallable;
|
_onPickResultCallable;
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -1553,7 +1554,7 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
Future<List<ThermionEntity>> getChildEntities(
|
Future<List<ThermionEntity>> getChildEntities(
|
||||||
ThermionEntity parent, bool renderableOnly) async {
|
ThermionEntity parent, bool renderableOnly) async {
|
||||||
var count = get_entity_count(_sceneManager!, parent, renderableOnly);
|
var count = get_entity_count(_sceneManager!, parent, renderableOnly);
|
||||||
var out = allocator<Int>(count);
|
var out = allocator<EntityId>(count);
|
||||||
get_entities(_sceneManager!, parent, renderableOnly, out);
|
get_entities(_sceneManager!, parent, renderableOnly, out);
|
||||||
var outList =
|
var outList =
|
||||||
List.generate(count, (index) => out[index]).cast<ThermionEntity>();
|
List.generate(count, (index) => out[index]).cast<ThermionEntity>();
|
||||||
@@ -1612,9 +1613,9 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
// ignore: sdk_version_since
|
// ignore: sdk_version_since
|
||||||
|
|
||||||
if (callback != null) {
|
if (callback != null) {
|
||||||
var ptr =
|
var ptr = NativeCallable<
|
||||||
NativeCallable<Void Function(Int entityId1, Int entityId2)>.listener(
|
Void Function(
|
||||||
callback);
|
EntityId entityId1, EntityId entityId2)>.listener(callback);
|
||||||
add_collision_component(
|
add_collision_component(
|
||||||
_sceneManager!, entity, ptr.nativeFunction, affectsTransform);
|
_sceneManager!, entity, ptr.nativeFunction, affectsTransform);
|
||||||
_collisions[entity] = ptr;
|
_collisions[entity] = ptr;
|
||||||
@@ -1699,11 +1700,11 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
@override
|
@override
|
||||||
Future setParent(ThermionEntity child, ThermionEntity parent) async {
|
Future setParent(ThermionEntity child, ThermionEntity parent, { bool preserveScaling = false}) async {
|
||||||
if (_sceneManager == null) {
|
if (_sceneManager == null) {
|
||||||
throw Exception("Asset manager must be non-null");
|
throw Exception("Asset manager must be non-null");
|
||||||
}
|
}
|
||||||
set_parent(_sceneManager!, child, parent);
|
set_parent(_sceneManager!, child, parent, preserveScaling);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -1736,4 +1737,11 @@ class ThermionViewerFFI extends ThermionViewer {
|
|||||||
Future setPriority(ThermionEntity entityId, int priority) async {
|
Future setPriority(ThermionEntity entityId, int priority) async {
|
||||||
set_priority(_sceneManager!, entityId, priority);
|
set_priority(_sceneManager!, entityId, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<v64.Aabb2> getBoundingBox(ThermionEntity entityId) async {
|
||||||
|
final result = get_bounding_box(_sceneManager!, entityId);
|
||||||
|
return v64.Aabb2.minMax(v64.Vector2(result.minX, result.minY),
|
||||||
|
v64.Vector2(result.maxX, result.maxY));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:thermion_dart/thermion_dart/entities/abstract_gizmo.dart';
|
||||||
import 'package:thermion_dart/thermion_dart/scene.dart';
|
import 'package:thermion_dart/thermion_dart/scene.dart';
|
||||||
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
|
import 'package:thermion_dart/thermion_dart/thermion_viewer.dart';
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
import 'package:vector_math/vector_math_64.dart';
|
||||||
@@ -608,7 +609,7 @@ class ThermionViewerStub extends ThermionViewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future setParent(ThermionEntity child, ThermionEntity parent) {
|
Future setParent(ThermionEntity child, ThermionEntity parent, { bool preserveScaling = false}) {
|
||||||
// TODO: implement setParent
|
// TODO: implement setParent
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
@@ -757,4 +758,10 @@ class ThermionViewerStub extends ThermionViewer {
|
|||||||
// TODO: implement capture
|
// TODO: implement capture
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Aabb2> getBoundingBox(ThermionEntity entity) {
|
||||||
|
// TODO: implement getBoundingBox
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
18
thermion_dart/native/include/Aabb2.h
Normal file
18
thermion_dart/native/include/Aabb2.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
struct Aabb2 {
|
||||||
|
float minX;
|
||||||
|
float minY;
|
||||||
|
float maxX;
|
||||||
|
float maxY;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct Aabb2 Aabb2;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
48
thermion_dart/native/include/Gizmo.hpp
Normal file
48
thermion_dart/native/include/Gizmo.hpp
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <utils/Entity.h>
|
||||||
|
#include <filament/Engine.h>
|
||||||
|
#include <filament/Material.h>
|
||||||
|
#include <filament/MaterialInstance.h>
|
||||||
|
#include <filament/Scene.h>
|
||||||
|
#include <filament/Camera.h>
|
||||||
|
#include <filament/View.h>
|
||||||
|
|
||||||
|
#include <gltfio/AssetLoader.h>
|
||||||
|
#include <gltfio/FilamentAsset.h>
|
||||||
|
#include <gltfio/FilamentInstance.h>
|
||||||
|
#include <gltfio/ResourceLoader.h>
|
||||||
|
|
||||||
|
#include <filament/IndexBuffer.h>
|
||||||
|
#include <filament/InstanceBuffer.h>
|
||||||
|
|
||||||
|
#include "material/gizmo.h"
|
||||||
|
|
||||||
|
#include "Aabb2.h"
|
||||||
|
|
||||||
|
using namespace filament;
|
||||||
|
using namespace utils;
|
||||||
|
|
||||||
|
|
||||||
|
class Gizmo {
|
||||||
|
public:
|
||||||
|
Gizmo(Engine* const engine);
|
||||||
|
void updateTransform();
|
||||||
|
void destroy(Engine* const engine);
|
||||||
|
Entity x() {
|
||||||
|
return _entities[0];
|
||||||
|
};
|
||||||
|
Entity y() {
|
||||||
|
return _entities[1];
|
||||||
|
};
|
||||||
|
Entity z() {
|
||||||
|
return _entities[2];
|
||||||
|
};
|
||||||
|
Entity center() {
|
||||||
|
return _entities[3];
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
utils::Entity _entities[4];
|
||||||
|
Material* _material;
|
||||||
|
MaterialInstance* _materialInstances[4];
|
||||||
|
};
|
||||||
@@ -6,6 +6,8 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include <filament/Scene.h>
|
#include <filament/Scene.h>
|
||||||
|
#include <filament/Camera.h>
|
||||||
|
#include <filament/View.h>
|
||||||
|
|
||||||
#include <gltfio/AssetLoader.h>
|
#include <gltfio/AssetLoader.h>
|
||||||
#include <gltfio/FilamentAsset.h>
|
#include <gltfio/FilamentAsset.h>
|
||||||
@@ -17,11 +19,13 @@
|
|||||||
|
|
||||||
#include "material/gizmo.h"
|
#include "material/gizmo.h"
|
||||||
#include "utils/NameComponentManager.h"
|
#include "utils/NameComponentManager.h"
|
||||||
|
#include "Gizmo.hpp"
|
||||||
#include "ResourceBuffer.hpp"
|
#include "ResourceBuffer.hpp"
|
||||||
#include "components/CollisionComponentManager.hpp"
|
#include "components/CollisionComponentManager.hpp"
|
||||||
#include "components/AnimationComponentManager.hpp"
|
#include "components/AnimationComponentManager.hpp"
|
||||||
|
|
||||||
#include "tsl/robin_map.h"
|
#include "tsl/robin_map.h"
|
||||||
|
#include "Aabb2.h"
|
||||||
|
|
||||||
namespace thermion_filament
|
namespace thermion_filament
|
||||||
{
|
{
|
||||||
@@ -37,7 +41,8 @@ namespace thermion_filament
|
|||||||
class SceneManager
|
class SceneManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SceneManager(const ResourceLoaderWrapperImpl *const loader,
|
SceneManager(View* view,
|
||||||
|
const ResourceLoaderWrapperImpl *const loader,
|
||||||
Engine *engine,
|
Engine *engine,
|
||||||
Scene *scene,
|
Scene *scene,
|
||||||
const char *uberArchivePath);
|
const char *uberArchivePath);
|
||||||
@@ -146,7 +151,7 @@ namespace thermion_filament
|
|||||||
void addCollisionComponent(EntityId entity, void (*onCollisionCallback)(const EntityId entityId1, const EntityId entityId2), bool affectsCollidingTransform);
|
void addCollisionComponent(EntityId entity, void (*onCollisionCallback)(const EntityId entityId1, const EntityId entityId2), bool affectsCollidingTransform);
|
||||||
void removeCollisionComponent(EntityId entityId);
|
void removeCollisionComponent(EntityId entityId);
|
||||||
EntityId getParent(EntityId child);
|
EntityId getParent(EntityId child);
|
||||||
void setParent(EntityId child, EntityId parent);
|
void setParent(EntityId child, EntityId parent, bool preserveScaling);
|
||||||
bool addAnimationComponent(EntityId entity);
|
bool addAnimationComponent(EntityId entity);
|
||||||
void removeAnimationComponent(EntityId entity);
|
void removeAnimationComponent(EntityId entity);
|
||||||
|
|
||||||
@@ -165,11 +170,18 @@ namespace thermion_filament
|
|||||||
void setPriority(EntityId entity, int priority);
|
void setPriority(EntityId entity, int priority);
|
||||||
|
|
||||||
/// @brief returns the gizmo entity, used to manipulate the global transform for entities
|
/// @brief returns the gizmo entity, used to manipulate the global transform for entities
|
||||||
/// @param out a pointer to an array of three EntityId {x, y, z}
|
/// @param out a pointer sized large enough to hold three EntityId values (representing the x, y, and z axis of the translation gizmo).
|
||||||
/// @return
|
/// @return
|
||||||
///
|
///
|
||||||
void getGizmo(EntityId *out);
|
void getGizmo(EntityId *out);
|
||||||
|
|
||||||
|
|
||||||
|
/// @brief returns the 2D min/max viewport coordinates of the bounding box for the specified enitty;
|
||||||
|
/// @param out a pointer large enough to store four floats (the min/max coordinates of the bounding box)
|
||||||
|
/// @return
|
||||||
|
///
|
||||||
|
Aabb2 getBoundingBox(EntityId entity);
|
||||||
|
|
||||||
friend class FilamentViewer;
|
friend class FilamentViewer;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -177,6 +189,7 @@ namespace thermion_filament
|
|||||||
const ResourceLoaderWrapperImpl *const _resourceLoaderWrapper;
|
const ResourceLoaderWrapperImpl *const _resourceLoaderWrapper;
|
||||||
Engine *_engine;
|
Engine *_engine;
|
||||||
Scene *_scene;
|
Scene *_scene;
|
||||||
|
View* _view;
|
||||||
gltfio::MaterialProvider *_ubershaderProvider = nullptr;
|
gltfio::MaterialProvider *_ubershaderProvider = nullptr;
|
||||||
gltfio::ResourceLoader *_gltfResourceLoader = nullptr;
|
gltfio::ResourceLoader *_gltfResourceLoader = nullptr;
|
||||||
gltfio::TextureProvider *_stbDecoder = nullptr;
|
gltfio::TextureProvider *_stbDecoder = nullptr;
|
||||||
@@ -203,9 +216,8 @@ namespace thermion_filament
|
|||||||
const char *entityName);
|
const char *entityName);
|
||||||
|
|
||||||
EntityId addGizmo();
|
EntityId addGizmo();
|
||||||
utils::Entity _gizmo[3];
|
Gizmo* _gizmo = nullptr;
|
||||||
Material* _gizmoMaterial;
|
|
||||||
MaterialInstance* _gizmoMaterialInstances[3];
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "ResourceBuffer.hpp"
|
#include "ResourceBuffer.hpp"
|
||||||
|
#include "Aabb2.h"
|
||||||
|
|
||||||
typedef int32_t EntityId;
|
typedef int32_t EntityId;
|
||||||
typedef int32_t _ManipulatorMode;
|
typedef int32_t _ManipulatorMode;
|
||||||
@@ -244,10 +245,11 @@ extern "C"
|
|||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE EntityId create_geometry(void *const viewer, float *vertices, int numVertices, uint16_t *indices, int numIndices, int primitiveType, const char *materialPath);
|
EMSCRIPTEN_KEEPALIVE EntityId create_geometry(void *const viewer, float *vertices, int numVertices, uint16_t *indices, int numIndices, int primitiveType, const char *materialPath);
|
||||||
EMSCRIPTEN_KEEPALIVE EntityId get_parent(void *const sceneManager, EntityId child);
|
EMSCRIPTEN_KEEPALIVE EntityId get_parent(void *const sceneManager, EntityId child);
|
||||||
EMSCRIPTEN_KEEPALIVE void set_parent(void *const sceneManager, EntityId child, EntityId parent);
|
EMSCRIPTEN_KEEPALIVE void set_parent(void *const sceneManager, EntityId child, EntityId parent, bool preserveScaling);
|
||||||
EMSCRIPTEN_KEEPALIVE void test_collisions(void *const sceneManager, EntityId entity);
|
EMSCRIPTEN_KEEPALIVE void test_collisions(void *const sceneManager, EntityId entity);
|
||||||
EMSCRIPTEN_KEEPALIVE void set_priority(void *const sceneManager, EntityId entityId, int priority);
|
EMSCRIPTEN_KEEPALIVE void set_priority(void *const sceneManager, EntityId entityId, int priority);
|
||||||
EMSCRIPTEN_KEEPALIVE void get_gizmo(void *const sceneManager, EntityId *out);
|
EMSCRIPTEN_KEEPALIVE void get_gizmo(void *const sceneManager, EntityId *out);
|
||||||
|
EMSCRIPTEN_KEEPALIVE Aabb2 get_bounding_box(void *const sceneManager, EntityId entity);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
199
thermion_dart/native/src/Gizmo.cpp
Normal file
199
thermion_dart/native/src/Gizmo.cpp
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
#include "Gizmo.hpp"
|
||||||
|
|
||||||
|
#include <filament/Engine.h>
|
||||||
|
#include <utils/Entity.h>
|
||||||
|
#include <utils/EntityManager.h>
|
||||||
|
#include <filament/RenderableManager.h>
|
||||||
|
#include <filament/TransformManager.h>
|
||||||
|
|
||||||
|
#include "material/gizmo.h"
|
||||||
|
#include "Log.hpp"
|
||||||
|
|
||||||
|
Gizmo::Gizmo(Engine* const engine)
|
||||||
|
{
|
||||||
|
_material =
|
||||||
|
Material::Builder()
|
||||||
|
.package(GIZMO_GIZMO_DATA, GIZMO_GIZMO_SIZE)
|
||||||
|
.build(*engine);
|
||||||
|
|
||||||
|
// Line and arrow vertices
|
||||||
|
float lineLength = 0.8f;
|
||||||
|
float lineWidth = 0.005f;
|
||||||
|
float arrowLength = 0.2f;
|
||||||
|
float arrowWidth = 0.03f;
|
||||||
|
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[54]{
|
||||||
|
// 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 (30 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<float *>(buffer); }));
|
||||||
|
|
||||||
|
auto ib = IndexBuffer::Builder().indexCount(54).bufferType(IndexBuffer::IndexType::USHORT).build(*engine);
|
||||||
|
ib->setBuffer(*engine, IndexBuffer::BufferDescriptor(
|
||||||
|
indices, 54 * sizeof(uint16_t),
|
||||||
|
[](void *buffer, size_t size, void *)
|
||||||
|
{ delete[] static_cast<uint16_t *>(buffer); }));
|
||||||
|
|
||||||
|
auto &entityManager = EntityManager::get();
|
||||||
|
|
||||||
|
// Create the three axes
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
_entities[i] = entityManager.create();
|
||||||
|
_materialInstances[i] = _material->createInstance();
|
||||||
|
|
||||||
|
math::float3 color;
|
||||||
|
math::mat4f transform;
|
||||||
|
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case 0: // X-axis (Red)
|
||||||
|
color = {1.0f, 0.0f, 0.0f};
|
||||||
|
transform = math::mat4f::rotation(math::F_PI_2, math::float3{0, 1, 0});
|
||||||
|
break;
|
||||||
|
case 1: // Y-axis (Green)
|
||||||
|
color = {0.0f, 1.0f, 0.0f};
|
||||||
|
transform = math::mat4f::rotation(-math::F_PI_2, math::float3{1, 0, 0});
|
||||||
|
break;
|
||||||
|
case 2: // Z-axis (Blue)
|
||||||
|
color = {0.0f, 0.0f, 1.0f};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_materialInstances[i]->setParameter("color", color);
|
||||||
|
|
||||||
|
RenderableManager::Builder(1)
|
||||||
|
.boundingBox({{0, 0, (lineLength + arrowLength) / 2}, {arrowWidth / 2, arrowWidth / 2, (lineLength + arrowLength) / 2}})
|
||||||
|
.material(0, _materialInstances[i])
|
||||||
|
.geometry(0, RenderableManager::PrimitiveType::TRIANGLES, vb, ib, 0, 54)
|
||||||
|
.culling(false)
|
||||||
|
.receiveShadows(false)
|
||||||
|
.castShadows(false)
|
||||||
|
.build(*engine, _entities[i]);
|
||||||
|
|
||||||
|
auto &transformManager = engine->getTransformManager();
|
||||||
|
auto instance = transformManager.getInstance(_entities[i]);
|
||||||
|
transformManager.setTransform(instance, transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the black cube (center cube)
|
||||||
|
_entities[3] = entityManager.create();
|
||||||
|
_materialInstances[3] = _material->createInstance();
|
||||||
|
_materialInstances[3]->setParameter("color", math::float3{0.0f, 0.0f, 0.0f}); // Black color
|
||||||
|
|
||||||
|
// Create center cube vertices
|
||||||
|
float centerCubeSize = 0.05f;
|
||||||
|
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<float *>(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<uint16_t *>(buffer); }));
|
||||||
|
|
||||||
|
RenderableManager::Builder(1)
|
||||||
|
.boundingBox({{}, {centerCubeSize, centerCubeSize, centerCubeSize}})
|
||||||
|
.material(0, _materialInstances[3])
|
||||||
|
.geometry(0, RenderableManager::PrimitiveType::TRIANGLES, centerCubeVb, centerCubeIb, 0, 36)
|
||||||
|
.culling(false)
|
||||||
|
.build(*engine, _entities[3]);
|
||||||
|
|
||||||
|
auto &rm = engine->getRenderableManager();
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
rm.setPriority(rm.getInstance(_entities[i]), 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gizmo::destroy(Engine *const engine) {
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
engine->destroy(_entities[i]);
|
||||||
|
engine->destroy(_materialInstances[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
engine->destroy(_material);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gizmo::updateTransform()
|
||||||
|
{
|
||||||
|
Log("Updating gizmo transform");
|
||||||
|
// // Get screen-space position of the entity
|
||||||
|
// math::float4 entityScreenPos = _view->getViewProjectionMatrix() * entityWorldPosition;
|
||||||
|
|
||||||
|
// // Convert to NDC space
|
||||||
|
// entityScreenPos /= entityScreenPos.w;
|
||||||
|
|
||||||
|
// // Convert to screen space
|
||||||
|
// float screenX = (entityScreenPos.x * 0.5f + 0.5f) * viewportWidth;
|
||||||
|
// float screenY = (entityScreenPos.y * 0.5f + 0.5f) * viewportHeight;
|
||||||
|
|
||||||
|
// // Set gizmo position
|
||||||
|
// gizmo->setPosition({screenX, screenY, 0});
|
||||||
|
|
||||||
|
// // Scale gizmo based on viewport size
|
||||||
|
// float scale = viewportHeight * 0.1f; // 10% of screen height, for example
|
||||||
|
// gizmo->setScale({scale, scale, 1});
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <filament/TransformManager.h>
|
#include <filament/TransformManager.h>
|
||||||
#include <filament/Texture.h>
|
#include <filament/Texture.h>
|
||||||
#include <filament/RenderableManager.h>
|
#include <filament/RenderableManager.h>
|
||||||
|
#include <filament/Viewport.h>
|
||||||
|
|
||||||
#include <utils/EntityManager.h>
|
#include <utils/EntityManager.h>
|
||||||
|
|
||||||
@@ -43,11 +44,13 @@ namespace thermion_filament
|
|||||||
using namespace filament::gltfio;
|
using namespace filament::gltfio;
|
||||||
using std::unique_ptr;
|
using std::unique_ptr;
|
||||||
|
|
||||||
SceneManager::SceneManager(const ResourceLoaderWrapperImpl *const resourceLoaderWrapper,
|
SceneManager::SceneManager(View *view,
|
||||||
|
const ResourceLoaderWrapperImpl *const resourceLoaderWrapper,
|
||||||
Engine *engine,
|
Engine *engine,
|
||||||
Scene *scene,
|
Scene *scene,
|
||||||
const char *uberArchivePath)
|
const char *uberArchivePath)
|
||||||
: _resourceLoaderWrapper(resourceLoaderWrapper),
|
: _view(view),
|
||||||
|
_resourceLoaderWrapper(resourceLoaderWrapper),
|
||||||
_engine(engine),
|
_engine(engine),
|
||||||
_scene(scene)
|
_scene(scene)
|
||||||
{
|
{
|
||||||
@@ -76,9 +79,9 @@ namespace thermion_filament
|
|||||||
utils::EntityManager &em = utils::EntityManager::get();
|
utils::EntityManager &em = utils::EntityManager::get();
|
||||||
|
|
||||||
_ncm = new NameComponentManager(em);
|
_ncm = new NameComponentManager(em);
|
||||||
|
|
||||||
_assetLoader = AssetLoader::create({_engine, _ubershaderProvider, _ncm, &em});
|
_assetLoader = AssetLoader::create({_engine, _ubershaderProvider, _ncm, &em});
|
||||||
|
|
||||||
_gltfResourceLoader->addTextureProvider("image/ktx2", _ktxDecoder);
|
_gltfResourceLoader->addTextureProvider("image/ktx2", _ktxDecoder);
|
||||||
_gltfResourceLoader->addTextureProvider("image/png", _stbDecoder);
|
_gltfResourceLoader->addTextureProvider("image/png", _stbDecoder);
|
||||||
_gltfResourceLoader->addTextureProvider("image/jpeg", _stbDecoder);
|
_gltfResourceLoader->addTextureProvider("image/jpeg", _stbDecoder);
|
||||||
@@ -87,24 +90,20 @@ namespace thermion_filament
|
|||||||
|
|
||||||
_collisionComponentManager = new CollisionComponentManager(tm);
|
_collisionComponentManager = new CollisionComponentManager(tm);
|
||||||
_animationComponentManager = new AnimationComponentManager(tm, _engine->getRenderableManager());
|
_animationComponentManager = new AnimationComponentManager(tm, _engine->getRenderableManager());
|
||||||
|
|
||||||
addGizmo();
|
_gizmo = new Gizmo(_engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneManager::~SceneManager()
|
SceneManager::~SceneManager()
|
||||||
{
|
{
|
||||||
|
|
||||||
destroyAll();
|
destroyAll();
|
||||||
|
|
||||||
for(int i =0; i < 3; i++) {
|
_gizmo->destroy(_engine);
|
||||||
_engine->destroy(_gizmo[i]);
|
|
||||||
_engine->destroy(_gizmoMaterialInstances[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
_engine->destroy(_gizmoMaterial);
|
|
||||||
_gltfResourceLoader->asyncCancelLoad();
|
_gltfResourceLoader->asyncCancelLoad();
|
||||||
_ubershaderProvider->destroyMaterials();
|
_ubershaderProvider->destroyMaterials();
|
||||||
|
|
||||||
delete _animationComponentManager;
|
delete _animationComponentManager;
|
||||||
delete _collisionComponentManager;
|
delete _collisionComponentManager;
|
||||||
delete _ncm;
|
delete _ncm;
|
||||||
@@ -114,7 +113,6 @@ namespace thermion_filament
|
|||||||
delete _ktxDecoder;
|
delete _ktxDecoder;
|
||||||
delete _ubershaderProvider;
|
delete _ubershaderProvider;
|
||||||
AssetLoader::destroy(&_assetLoader);
|
AssetLoader::destroy(&_assetLoader);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SceneManager::getInstanceCount(EntityId entityId)
|
int SceneManager::getInstanceCount(EntityId entityId)
|
||||||
@@ -454,7 +452,8 @@ namespace thermion_filament
|
|||||||
for (auto &asset : _assets)
|
for (auto &asset : _assets)
|
||||||
{
|
{
|
||||||
auto numInstances = asset.second->getAssetInstanceCount();
|
auto numInstances = asset.second->getAssetInstanceCount();
|
||||||
for(int i = 0; i < numInstances; i++) {
|
for (int i = 0; i < numInstances; i++)
|
||||||
|
{
|
||||||
auto instance = asset.second->getAssetInstances()[i];
|
auto instance = asset.second->getAssetInstances()[i];
|
||||||
for (int j = 0; j < instance->getEntityCount(); j++)
|
for (int j = 0; j < instance->getEntityCount(); j++)
|
||||||
{
|
{
|
||||||
@@ -499,21 +498,24 @@ namespace thermion_filament
|
|||||||
return pos->second;
|
return pos->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
math::mat4f SceneManager::getLocalTransform(EntityId entityId) {
|
math::mat4f SceneManager::getLocalTransform(EntityId entityId)
|
||||||
|
{
|
||||||
auto entity = Entity::import(entityId);
|
auto entity = Entity::import(entityId);
|
||||||
auto& tm = _engine->getTransformManager();
|
auto &tm = _engine->getTransformManager();
|
||||||
auto transformInstance = tm.getInstance(entity);
|
auto transformInstance = tm.getInstance(entity);
|
||||||
return tm.getTransform(transformInstance);
|
return tm.getTransform(transformInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
math::mat4f SceneManager::getWorldTransform(EntityId entityId) {
|
math::mat4f SceneManager::getWorldTransform(EntityId entityId)
|
||||||
|
{
|
||||||
auto entity = Entity::import(entityId);
|
auto entity = Entity::import(entityId);
|
||||||
auto& tm = _engine->getTransformManager();
|
auto &tm = _engine->getTransformManager();
|
||||||
auto transformInstance = tm.getInstance(entity);
|
auto transformInstance = tm.getInstance(entity);
|
||||||
return tm.getWorldTransform(transformInstance);
|
return tm.getWorldTransform(transformInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityId SceneManager::getBone(EntityId entityId, int skinIndex, int boneIndex) {
|
EntityId SceneManager::getBone(EntityId entityId, int skinIndex, int boneIndex)
|
||||||
|
{
|
||||||
auto *instance = getInstanceByEntityId(entityId);
|
auto *instance = getInstanceByEntityId(entityId);
|
||||||
if (!instance)
|
if (!instance)
|
||||||
{
|
{
|
||||||
@@ -533,7 +535,8 @@ namespace thermion_filament
|
|||||||
return Entity::smuggle(joint);
|
return Entity::smuggle(joint);
|
||||||
}
|
}
|
||||||
|
|
||||||
math::mat4f SceneManager::getInverseBindMatrix(EntityId entityId, int skinIndex, int boneIndex) {
|
math::mat4f SceneManager::getInverseBindMatrix(EntityId entityId, int skinIndex, int boneIndex)
|
||||||
|
{
|
||||||
auto *instance = getInstanceByEntityId(entityId);
|
auto *instance = getInstanceByEntityId(entityId);
|
||||||
if (!instance)
|
if (!instance)
|
||||||
{
|
{
|
||||||
@@ -552,7 +555,6 @@ namespace thermion_filament
|
|||||||
return inverseBindMatrix;
|
return inverseBindMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SceneManager::setBoneTransform(EntityId entityId, int32_t skinIndex, int boneIndex, math::mat4f transform)
|
bool SceneManager::setBoneTransform(EntityId entityId, int32_t skinIndex, int boneIndex, math::mat4f transform)
|
||||||
{
|
{
|
||||||
std::lock_guard lock(_mutex);
|
std::lock_guard lock(_mutex);
|
||||||
@@ -781,7 +783,7 @@ namespace thermion_filament
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneManager::clearMorphAnimationBuffer(
|
void SceneManager::clearMorphAnimationBuffer(
|
||||||
EntityId entityId)
|
EntityId entityId)
|
||||||
{
|
{
|
||||||
std::lock_guard lock(_mutex);
|
std::lock_guard lock(_mutex);
|
||||||
@@ -865,12 +867,12 @@ namespace thermion_filament
|
|||||||
TransformManager &transformManager = _engine->getTransformManager();
|
TransformManager &transformManager = _engine->getTransformManager();
|
||||||
|
|
||||||
//
|
//
|
||||||
// To reset the skeleton to its rest pose, we could just call animator->resetBoneMatrices(),
|
// To reset the skeleton to its rest pose, we could just call animator->resetBoneMatrices(),
|
||||||
// which sets all bone matrices to the identity matrix. However, any subsequent calls to animator->updateBoneMatrices()
|
// which sets all bone matrices to the identity matrix. However, any subsequent calls to animator->updateBoneMatrices()
|
||||||
// may result in unexpected poses, because that method uses each bone's transform to calculate
|
// may result in unexpected poses, because that method uses each bone's transform to calculate
|
||||||
// the bone matrices (and resetBoneMatrices does not affect this transform).
|
// the bone matrices (and resetBoneMatrices does not affect this transform).
|
||||||
// To "fully" reset the bone, we need to set its local transform (i.e. relative to its parent)
|
// To "fully" reset the bone, we need to set its local transform (i.e. relative to its parent)
|
||||||
// to its original orientation in rest pose.
|
// to its original orientation in rest pose.
|
||||||
//
|
//
|
||||||
// This can be calculated as:
|
// This can be calculated as:
|
||||||
//
|
//
|
||||||
@@ -879,7 +881,7 @@ namespace thermion_filament
|
|||||||
// (where bindMatrix is the inverse of the inverseBindMatrix).
|
// (where bindMatrix is the inverse of the inverseBindMatrix).
|
||||||
//
|
//
|
||||||
// The only requirement is that parent bone transforms are reset before child bone transforms.
|
// The only requirement is that parent bone transforms are reset before child bone transforms.
|
||||||
// glTF/Filament does not guarantee that parent bones are listed before child bones under a FilamentInstance.
|
// glTF/Filament does not guarantee that parent bones are listed before child bones under a FilamentInstance.
|
||||||
// We ensure that parents are reset before children by:
|
// We ensure that parents are reset before children by:
|
||||||
// - pushing all bones onto a stack
|
// - pushing all bones onto a stack
|
||||||
// - iterate over the stack
|
// - iterate over the stack
|
||||||
@@ -891,16 +893,16 @@ namespace thermion_filament
|
|||||||
// - pop the bone, reset its transform and mark it as completed
|
// - pop the bone, reset its transform and mark it as completed
|
||||||
for (int skinIndex = 0; skinIndex < skinCount; skinIndex++)
|
for (int skinIndex = 0; skinIndex < skinCount; skinIndex++)
|
||||||
{
|
{
|
||||||
std::unordered_set<Entity,Entity::Hasher> joints;
|
std::unordered_set<Entity, Entity::Hasher> joints;
|
||||||
std::unordered_set<Entity,Entity::Hasher> completed;
|
std::unordered_set<Entity, Entity::Hasher> completed;
|
||||||
std::stack<Entity> stack;
|
std::stack<Entity> stack;
|
||||||
|
|
||||||
auto transforms = getBoneRestTranforms(entityId, skinIndex);
|
auto transforms = getBoneRestTranforms(entityId, skinIndex);
|
||||||
|
|
||||||
for (int i = 0; i < instance->getJointCountAt(skinIndex); i++)
|
for (int i = 0; i < instance->getJointCountAt(skinIndex); i++)
|
||||||
{
|
{
|
||||||
auto restTransform = transforms->at(i);
|
auto restTransform = transforms->at(i);
|
||||||
const auto& joint = instance->getJointsAt(skinIndex)[i];
|
const auto &joint = instance->getJointsAt(skinIndex)[i];
|
||||||
auto transformInstance = transformManager.getInstance(joint);
|
auto transformInstance = transformManager.getInstance(joint);
|
||||||
transformManager.setTransform(transformInstance, restTransform);
|
transformManager.setTransform(transformInstance, restTransform);
|
||||||
}
|
}
|
||||||
@@ -908,7 +910,8 @@ namespace thermion_filament
|
|||||||
instance->getAnimator()->updateBoneMatrices();
|
instance->getAnimator()->updateBoneMatrices();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<std::vector<math::mat4f>> SceneManager::getBoneRestTranforms(EntityId entityId, int skinIndex) {
|
std::unique_ptr<std::vector<math::mat4f>> SceneManager::getBoneRestTranforms(EntityId entityId, int skinIndex)
|
||||||
|
{
|
||||||
|
|
||||||
auto transforms = std::make_unique<std::vector<math::mat4f>>();
|
auto transforms = std::make_unique<std::vector<math::mat4f>>();
|
||||||
|
|
||||||
@@ -933,12 +936,12 @@ namespace thermion_filament
|
|||||||
transforms->resize(instance->getJointCountAt(skinIndex));
|
transforms->resize(instance->getJointCountAt(skinIndex));
|
||||||
|
|
||||||
//
|
//
|
||||||
// To reset the skeleton to its rest pose, we could just call animator->resetBoneMatrices(),
|
// To reset the skeleton to its rest pose, we could just call animator->resetBoneMatrices(),
|
||||||
// which sets all bone matrices to the identity matrix. However, any subsequent calls to animator->updateBoneMatrices()
|
// which sets all bone matrices to the identity matrix. However, any subsequent calls to animator->updateBoneMatrices()
|
||||||
// may result in unexpected poses, because that method uses each bone's transform to calculate
|
// may result in unexpected poses, because that method uses each bone's transform to calculate
|
||||||
// the bone matrices (and resetBoneMatrices does not affect this transform).
|
// the bone matrices (and resetBoneMatrices does not affect this transform).
|
||||||
// To "fully" reset the bone, we need to set its local transform (i.e. relative to its parent)
|
// To "fully" reset the bone, we need to set its local transform (i.e. relative to its parent)
|
||||||
// to its original orientation in rest pose.
|
// to its original orientation in rest pose.
|
||||||
//
|
//
|
||||||
// This can be calculated as:
|
// This can be calculated as:
|
||||||
//
|
//
|
||||||
@@ -947,7 +950,7 @@ namespace thermion_filament
|
|||||||
// (where bindMatrix is the inverse of the inverseBindMatrix).
|
// (where bindMatrix is the inverse of the inverseBindMatrix).
|
||||||
//
|
//
|
||||||
// The only requirement is that parent bone transforms are reset before child bone transforms.
|
// The only requirement is that parent bone transforms are reset before child bone transforms.
|
||||||
// glTF/Filament does not guarantee that parent bones are listed before child bones under a FilamentInstance.
|
// glTF/Filament does not guarantee that parent bones are listed before child bones under a FilamentInstance.
|
||||||
// We ensure that parents are reset before children by:
|
// We ensure that parents are reset before children by:
|
||||||
// - pushing all bones onto a stack
|
// - pushing all bones onto a stack
|
||||||
// - iterate over the stack
|
// - iterate over the stack
|
||||||
@@ -958,22 +961,23 @@ namespace thermion_filament
|
|||||||
// - otherwise
|
// - otherwise
|
||||||
// - pop the bone, reset its transform and mark it as completed
|
// - pop the bone, reset its transform and mark it as completed
|
||||||
std::vector<Entity> joints;
|
std::vector<Entity> joints;
|
||||||
std::unordered_set<Entity,Entity::Hasher> completed;
|
std::unordered_set<Entity, Entity::Hasher> completed;
|
||||||
std::stack<Entity> stack;
|
std::stack<Entity> stack;
|
||||||
|
|
||||||
for (int i = 0; i < instance->getJointCountAt(skinIndex); i++)
|
for (int i = 0; i < instance->getJointCountAt(skinIndex); i++)
|
||||||
{
|
{
|
||||||
const auto& joint = instance->getJointsAt(skinIndex)[i];
|
const auto &joint = instance->getJointsAt(skinIndex)[i];
|
||||||
joints.push_back(joint);
|
joints.push_back(joint);
|
||||||
stack.push(joint);
|
stack.push(joint);
|
||||||
}
|
}
|
||||||
|
|
||||||
while(!stack.empty())
|
while (!stack.empty())
|
||||||
{
|
{
|
||||||
const auto& joint = stack.top();
|
const auto &joint = stack.top();
|
||||||
|
|
||||||
// if we've already handled this node previously (e.g. when we encountered it as a parent), then skip
|
// if we've already handled this node previously (e.g. when we encountered it as a parent), then skip
|
||||||
if(completed.find(joint) != completed.end()) {
|
if (completed.find(joint) != completed.end())
|
||||||
|
{
|
||||||
stack.pop();
|
stack.pop();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -981,23 +985,25 @@ namespace thermion_filament
|
|||||||
const auto transformInstance = transformManager.getInstance(joint);
|
const auto transformInstance = transformManager.getInstance(joint);
|
||||||
auto parent = transformManager.getParent(transformInstance);
|
auto parent = transformManager.getParent(transformInstance);
|
||||||
|
|
||||||
// we need to handle parent joints before handling their children
|
// we need to handle parent joints before handling their children
|
||||||
// therefore, if this joint has a parent that hasn't been handled yet,
|
// therefore, if this joint has a parent that hasn't been handled yet,
|
||||||
// push the parent to the top of the stack and start the loop again
|
// push the parent to the top of the stack and start the loop again
|
||||||
const auto& jointIter = std::find(joints.begin(), joints.end(), joint);
|
const auto &jointIter = std::find(joints.begin(), joints.end(), joint);
|
||||||
auto parentIter = std::find(joints.begin(), joints.end(), parent);
|
auto parentIter = std::find(joints.begin(), joints.end(), parent);
|
||||||
|
|
||||||
if(parentIter != joints.end() && completed.find(parent) == completed.end()) {
|
if (parentIter != joints.end() && completed.find(parent) == completed.end())
|
||||||
|
{
|
||||||
stack.push(parent);
|
stack.push(parent);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise let's get the inverse bind matrix for the joint
|
// otherwise let's get the inverse bind matrix for the joint
|
||||||
math::mat4f inverseBindMatrix;
|
math::mat4f inverseBindMatrix;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (int i = 0; i < instance->getJointCountAt(skinIndex); i++)
|
for (int i = 0; i < instance->getJointCountAt(skinIndex); i++)
|
||||||
{
|
{
|
||||||
if(instance->getJointsAt(skinIndex)[i] == joint) {
|
if (instance->getJointsAt(skinIndex)[i] == joint)
|
||||||
|
{
|
||||||
inverseBindMatrix = instance->getInverseBindMatricesAt(skinIndex)[i];
|
inverseBindMatrix = instance->getInverseBindMatricesAt(skinIndex)[i];
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
@@ -1007,7 +1013,8 @@ namespace thermion_filament
|
|||||||
|
|
||||||
// now we need to ascend back up the hierarchy to calculate the modelSpaceTransform
|
// now we need to ascend back up the hierarchy to calculate the modelSpaceTransform
|
||||||
math::mat4f modelSpaceTransform;
|
math::mat4f modelSpaceTransform;
|
||||||
while(parentIter != joints.end()) {
|
while (parentIter != joints.end())
|
||||||
|
{
|
||||||
const auto transformInstance = transformManager.getInstance(parent);
|
const auto transformInstance = transformManager.getInstance(parent);
|
||||||
const auto parentIndex = distance(joints.begin(), parentIter);
|
const auto parentIndex = distance(joints.begin(), parentIter);
|
||||||
const auto transform = transforms->at(parentIndex);
|
const auto transform = transforms->at(parentIndex);
|
||||||
@@ -1016,9 +1023,9 @@ namespace thermion_filament
|
|||||||
parentIter = std::find(joints.begin(), joints.end(), parent);
|
parentIter = std::find(joints.begin(), joints.end(), parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto bindMatrix = inverse(inverseBindMatrix);
|
const auto bindMatrix = inverse(inverseBindMatrix);
|
||||||
|
|
||||||
const auto inverseModelSpaceTransform = inverse(modelSpaceTransform);
|
const auto inverseModelSpaceTransform = inverse(modelSpaceTransform);
|
||||||
|
|
||||||
const auto jointIndex = distance(joints.begin(), jointIter);
|
const auto jointIndex = distance(joints.begin(), jointIter);
|
||||||
transforms->at(jointIndex) = inverseModelSpaceTransform * bindMatrix;
|
transforms->at(jointIndex) = inverseModelSpaceTransform * bindMatrix;
|
||||||
@@ -1028,7 +1035,8 @@ namespace thermion_filament
|
|||||||
return transforms;
|
return transforms;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SceneManager::updateBoneMatrices(EntityId entityId) {
|
bool SceneManager::updateBoneMatrices(EntityId entityId)
|
||||||
|
{
|
||||||
auto *instance = getInstanceByEntityId(entityId);
|
auto *instance = getInstanceByEntityId(entityId);
|
||||||
if (!instance)
|
if (!instance)
|
||||||
{
|
{
|
||||||
@@ -1046,11 +1054,13 @@ namespace thermion_filament
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SceneManager::setTransform(EntityId entityId, math::mat4f transform) {
|
bool SceneManager::setTransform(EntityId entityId, math::mat4f transform)
|
||||||
auto& tm = _engine->getTransformManager();
|
{
|
||||||
const auto& entity = Entity::import(entityId);
|
auto &tm = _engine->getTransformManager();
|
||||||
|
const auto &entity = Entity::import(entityId);
|
||||||
auto transformInstance = tm.getInstance(entity);
|
auto transformInstance = tm.getInstance(entity);
|
||||||
if(!transformInstance) {
|
if (!transformInstance)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
tm.setTransform(transformInstance, transform);
|
tm.setTransform(transformInstance, transform);
|
||||||
@@ -1059,11 +1069,11 @@ namespace thermion_filament
|
|||||||
|
|
||||||
bool SceneManager::addBoneAnimation(EntityId parentEntity,
|
bool SceneManager::addBoneAnimation(EntityId parentEntity,
|
||||||
int skinIndex,
|
int skinIndex,
|
||||||
int boneIndex,
|
int boneIndex,
|
||||||
const float *const frameData,
|
const float *const frameData,
|
||||||
int numFrames,
|
int numFrames,
|
||||||
float frameLengthInMs,
|
float frameLengthInMs,
|
||||||
float fadeOutInSecs,
|
float fadeOutInSecs,
|
||||||
float fadeInInSecs,
|
float fadeInInSecs,
|
||||||
float maxDelta)
|
float maxDelta)
|
||||||
{
|
{
|
||||||
@@ -1122,7 +1132,8 @@ namespace thermion_filament
|
|||||||
animation.fadeInInSecs = fadeInInSecs;
|
animation.fadeInInSecs = fadeInInSecs;
|
||||||
animation.maxDelta = maxDelta;
|
animation.maxDelta = maxDelta;
|
||||||
animation.skinIndex = skinIndex;
|
animation.skinIndex = skinIndex;
|
||||||
if(!_animationComponentManager->hasComponent(instance->getRoot())) {
|
if (!_animationComponentManager->hasComponent(instance->getRoot()))
|
||||||
|
{
|
||||||
Log("ERROR: specified entity is not animatable (has no animation component attached).");
|
Log("ERROR: specified entity is not animatable (has no animation component attached).");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1135,7 +1146,7 @@ namespace thermion_filament
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneManager::playAnimation(EntityId entityId, int index, bool loop, bool reverse, bool replaceActive, float crossfade, float startOffset)
|
void SceneManager::playAnimation(EntityId entityId, int index, bool loop, bool reverse, bool replaceActive, float crossfade, float startOffset)
|
||||||
{
|
{
|
||||||
std::lock_guard lock(_mutex);
|
std::lock_guard lock(_mutex);
|
||||||
@@ -1160,7 +1171,7 @@ namespace thermion_filament
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_animationComponentManager->hasComponent(instance->getRoot()))
|
if (!_animationComponentManager->hasComponent(instance->getRoot()))
|
||||||
{
|
{
|
||||||
Log("ERROR: specified entity is not animatable (has no animation component attached).");
|
Log("ERROR: specified entity is not animatable (has no animation component attached).");
|
||||||
return;
|
return;
|
||||||
@@ -1210,13 +1221,16 @@ namespace thermion_filament
|
|||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
// don't play the animation if it's already running
|
// don't play the animation if it's already running
|
||||||
for(int i=0; i < animationComponent.gltfAnimations.size(); i++) {
|
for (int i = 0; i < animationComponent.gltfAnimations.size(); i++)
|
||||||
if(animationComponent.gltfAnimations[i].index == index) {
|
{
|
||||||
|
if (animationComponent.gltfAnimations[i].index == index)
|
||||||
|
{
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!found) {
|
if (!found)
|
||||||
|
{
|
||||||
animationComponent.gltfAnimations.push_back(animation);
|
animationComponent.gltfAnimations.push_back(animation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1244,9 +1258,9 @@ namespace thermion_filament
|
|||||||
auto &animationComponent = _animationComponentManager->elementAt<0>(animationComponentInstance);
|
auto &animationComponent = _animationComponentManager->elementAt<0>(animationComponentInstance);
|
||||||
|
|
||||||
auto erased = std::remove_if(animationComponent.gltfAnimations.begin(),
|
auto erased = std::remove_if(animationComponent.gltfAnimations.begin(),
|
||||||
animationComponent.gltfAnimations.end(),
|
animationComponent.gltfAnimations.end(),
|
||||||
[=](GltfAnimation &anim)
|
[=](GltfAnimation &anim)
|
||||||
{ return anim.index == index; });
|
{ return anim.index == index; });
|
||||||
animationComponent.gltfAnimations.erase(erased,
|
animationComponent.gltfAnimations.erase(erased,
|
||||||
animationComponent.gltfAnimations.end());
|
animationComponent.gltfAnimations.end());
|
||||||
}
|
}
|
||||||
@@ -1391,7 +1405,7 @@ namespace thermion_filament
|
|||||||
unique_ptr<std::vector<std::string>> names = std::make_unique<std::vector<std::string>>();
|
unique_ptr<std::vector<std::string>> names = std::make_unique<std::vector<std::string>>();
|
||||||
|
|
||||||
const auto *instance = getInstanceByEntityId(assetEntityId);
|
const auto *instance = getInstanceByEntityId(assetEntityId);
|
||||||
|
|
||||||
if (!instance)
|
if (!instance)
|
||||||
{
|
{
|
||||||
auto asset = getAssetByEntityId(assetEntityId);
|
auto asset = getAssetByEntityId(assetEntityId);
|
||||||
@@ -1401,7 +1415,8 @@ namespace thermion_filament
|
|||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
instance = asset->getInstance();
|
instance = asset->getInstance();
|
||||||
if(!instance) {
|
if (!instance)
|
||||||
|
{
|
||||||
Log("Warning - failed to find instance for specified asset. This is unexpected and probably indicates you are passing the wrong entity");
|
Log("Warning - failed to find instance for specified asset. This is unexpected and probably indicates you are passing the wrong entity");
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
@@ -1415,7 +1430,7 @@ namespace thermion_filament
|
|||||||
|
|
||||||
for (int i = 0; i < asset->getEntityCount(); i++)
|
for (int i = 0; i < asset->getEntityCount(); i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
utils::Entity e = entities[i];
|
utils::Entity e = entities[i];
|
||||||
if (e == target)
|
if (e == target)
|
||||||
{
|
{
|
||||||
@@ -1431,7 +1446,8 @@ namespace thermion_filament
|
|||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<vector<string>> SceneManager::getBoneNames(EntityId assetEntityId, int skinIndex) {
|
unique_ptr<vector<string>> SceneManager::getBoneNames(EntityId assetEntityId, int skinIndex)
|
||||||
|
{
|
||||||
|
|
||||||
unique_ptr<std::vector<std::string>> names = std::make_unique<std::vector<std::string>>();
|
unique_ptr<std::vector<std::string>> names = std::make_unique<std::vector<std::string>>();
|
||||||
|
|
||||||
@@ -1468,7 +1484,6 @@ namespace thermion_filament
|
|||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SceneManager::transformToUnitCube(EntityId entityId)
|
void SceneManager::transformToUnitCube(EntityId entityId)
|
||||||
{
|
{
|
||||||
const auto *instance = getInstanceByEntityId(entityId);
|
const auto *instance = getInstanceByEntityId(entityId);
|
||||||
@@ -1496,7 +1511,8 @@ namespace thermion_filament
|
|||||||
tm.setTransform(tm.getInstance(instance->getRoot()), transform);
|
tm.setTransform(tm.getInstance(instance->getRoot()), transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityId SceneManager::getParent(EntityId childEntityId) {
|
EntityId SceneManager::getParent(EntityId childEntityId)
|
||||||
|
{
|
||||||
auto &tm = _engine->getTransformManager();
|
auto &tm = _engine->getTransformManager();
|
||||||
const auto child = Entity::import(childEntityId);
|
const auto child = Entity::import(childEntityId);
|
||||||
const auto &childInstance = tm.getInstance(child);
|
const auto &childInstance = tm.getInstance(child);
|
||||||
@@ -1504,7 +1520,7 @@ namespace thermion_filament
|
|||||||
return Entity::smuggle(parent);
|
return Entity::smuggle(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneManager::setParent(EntityId childEntityId, EntityId parentEntityId)
|
void SceneManager::setParent(EntityId childEntityId, EntityId parentEntityId, bool preserveScaling)
|
||||||
{
|
{
|
||||||
auto &tm = _engine->getTransformManager();
|
auto &tm = _engine->getTransformManager();
|
||||||
const auto child = Entity::import(childEntityId);
|
const auto child = Entity::import(childEntityId);
|
||||||
@@ -1512,6 +1528,31 @@ namespace thermion_filament
|
|||||||
|
|
||||||
const auto &parentInstance = tm.getInstance(parent);
|
const auto &parentInstance = tm.getInstance(parent);
|
||||||
const auto &childInstance = tm.getInstance(child);
|
const auto &childInstance = tm.getInstance(child);
|
||||||
|
|
||||||
|
if (preserveScaling)
|
||||||
|
{
|
||||||
|
auto parentTransform = tm.getWorldTransform(parentInstance);
|
||||||
|
math::float3 parentTranslation;
|
||||||
|
math::quatf parentRotation;
|
||||||
|
math::float3 parentScale;
|
||||||
|
|
||||||
|
decomposeMatrix(parentTransform, &parentTranslation, &parentRotation, &parentScale);
|
||||||
|
|
||||||
|
auto childTransform = tm.getTransform(childInstance);
|
||||||
|
math::float3 childTranslation;
|
||||||
|
math::quatf childRotation;
|
||||||
|
math::float3 childScale;
|
||||||
|
|
||||||
|
decomposeMatrix(childTransform, &childTranslation, &childRotation, &childScale);
|
||||||
|
|
||||||
|
childScale = childScale * (1 / parentScale);
|
||||||
|
|
||||||
|
childTransform = composeMatrix(childTranslation, childRotation, childScale);
|
||||||
|
|
||||||
|
tm.setTransform(childInstance, childTransform);
|
||||||
|
}
|
||||||
|
|
||||||
|
// auto scale = childInstance.
|
||||||
tm.setParent(childInstance, parentInstance);
|
tm.setParent(childInstance, parentInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1587,12 +1628,16 @@ namespace thermion_filament
|
|||||||
_animationComponentManager->update();
|
_animationComponentManager->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SceneManager::updateTransforms()
|
void SceneManager::updateTransforms()
|
||||||
{
|
{
|
||||||
std::lock_guard lock(_mutex);
|
std::lock_guard lock(_mutex);
|
||||||
|
|
||||||
auto &tm = _engine->getTransformManager();
|
auto &tm = _engine->getTransformManager();
|
||||||
|
|
||||||
|
_gizmo->updateTransform();
|
||||||
|
|
||||||
for (const auto &[entityId, transformUpdate] : _transformUpdates)
|
for (const auto &[entityId, transformUpdate] : _transformUpdates)
|
||||||
{
|
{
|
||||||
const auto &pos = _instances.find(entityId);
|
const auto &pos = _instances.find(entityId);
|
||||||
@@ -1751,25 +1796,77 @@ namespace thermion_filament
|
|||||||
tm.setTransform(transformInstance, newTransform);
|
tm.setTransform(transformInstance, newTransform);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneManager::queuePositionUpdate(EntityId entity, float x, float y, float z, bool relative)
|
void SceneManager::queuePositionUpdate(EntityId entity, float x, float y, float z, bool relative)
|
||||||
|
{
|
||||||
|
std::lock_guard lock(_mutex);
|
||||||
|
|
||||||
|
const auto &pos = _transformUpdates.find(entity);
|
||||||
|
if (pos == _transformUpdates.end())
|
||||||
{
|
{
|
||||||
std::lock_guard lock(_mutex);
|
_transformUpdates.emplace(entity, std::make_tuple(math::float3(), true, math::quatf(1.0f), true, 1.0f));
|
||||||
|
|
||||||
const auto &pos = _transformUpdates.find(entity);
|
|
||||||
if (pos == _transformUpdates.end())
|
|
||||||
{
|
|
||||||
_transformUpdates.emplace(entity, std::make_tuple(math::float3(), true, math::quatf(1.0f), true, 1.0f));
|
|
||||||
}
|
|
||||||
auto curr = _transformUpdates[entity];
|
|
||||||
auto &trans = std::get<0>(curr);
|
|
||||||
trans.x = x;
|
|
||||||
trans.y = y;
|
|
||||||
trans.z = z;
|
|
||||||
|
|
||||||
auto &isRelative = std::get<1>(curr);
|
|
||||||
isRelative = relative;
|
|
||||||
_transformUpdates[entity] = curr;
|
|
||||||
}
|
}
|
||||||
|
auto curr = _transformUpdates[entity];
|
||||||
|
auto &trans = std::get<0>(curr);
|
||||||
|
|
||||||
|
const auto &tm = _engine->getTransformManager();
|
||||||
|
auto transformInstance = tm.getInstance(Entity::import(entity));
|
||||||
|
auto transform = tm.getTransform(transformInstance);
|
||||||
|
math::double4 position { 0.0f, 0.0f, 0.0f, 1.0f};
|
||||||
|
math::mat4 worldTransform = tm.getWorldTransformAccurate(transformInstance);
|
||||||
|
position = worldTransform * position;
|
||||||
|
|
||||||
|
// Get camera's view matrix and its inverse
|
||||||
|
const Camera &camera = _view->getCamera();
|
||||||
|
|
||||||
|
math::mat4 viewMatrix = camera.getViewMatrix();
|
||||||
|
math::mat4 invViewMatrix = inverse(viewMatrix);
|
||||||
|
|
||||||
|
// Transform object position to view space
|
||||||
|
math::double4 viewSpacePos = viewMatrix * position;
|
||||||
|
|
||||||
|
Log("viewSpacePos %f %f %f %f", viewSpacePos.x, viewSpacePos.y, viewSpacePos.z, viewSpacePos.w);
|
||||||
|
|
||||||
|
// Calculate plane distance from camera
|
||||||
|
float planeDistance = -viewSpacePos.z;
|
||||||
|
|
||||||
|
const auto &vp = _view->getViewport();
|
||||||
|
|
||||||
|
// Calculate viewport to world scale at the object's distance
|
||||||
|
float viewportToWorldScale = planeDistance * std::tan(camera.getFieldOfViewInDegrees(Camera::Fov::VERTICAL) * 0.5f * M_PI / 180.0f) * 2.0f / vp.height;
|
||||||
|
|
||||||
|
Log("viewportToWorldScale %f", viewportToWorldScale);
|
||||||
|
|
||||||
|
// Calculate view space delta
|
||||||
|
math::float4 viewSpaceDelta(
|
||||||
|
x * viewportToWorldScale,
|
||||||
|
-y * viewportToWorldScale, // Invert y-axis
|
||||||
|
z * viewportToWorldScale,
|
||||||
|
0.0f); // Use 0 for the w component as it's a direction, not a position
|
||||||
|
|
||||||
|
Log("viewSpaceDelta %f %f %f", viewSpaceDelta.x, viewSpaceDelta.y, viewSpaceDelta.z);
|
||||||
|
|
||||||
|
// Transform delta to world space
|
||||||
|
math::float4 worldDelta = invViewMatrix * viewSpaceDelta;
|
||||||
|
|
||||||
|
Log("worldDelta %f %f %f", worldDelta.x, worldDelta.y, worldDelta.z);
|
||||||
|
|
||||||
|
if (relative)
|
||||||
|
{
|
||||||
|
trans.x += worldDelta.x;
|
||||||
|
trans.y += worldDelta.y;
|
||||||
|
trans.z += worldDelta.z;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
trans.x = worldDelta.x;
|
||||||
|
trans.y = worldDelta.y;
|
||||||
|
trans.z = worldDelta.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &isRelative = std::get<1>(curr);
|
||||||
|
isRelative = relative;
|
||||||
|
_transformUpdates[entity] = curr;
|
||||||
|
}
|
||||||
|
|
||||||
void SceneManager::queueRotationUpdate(EntityId entity, float rads, float x, float y, float z, float w, bool relative)
|
void SceneManager::queueRotationUpdate(EntityId entity, float rads, float x, float y, float z, float w, bool relative)
|
||||||
{
|
{
|
||||||
@@ -2011,131 +2108,86 @@ namespace thermion_filament
|
|||||||
Log("Set instance renderable priority to %d", priority);
|
Log("Set instance renderable priority to %d", priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityId SceneManager::addGizmo()
|
Aabb2 SceneManager::getBoundingBox(EntityId entityId)
|
||||||
{
|
{
|
||||||
_gizmoMaterial =
|
const auto &camera = _view->getCamera();
|
||||||
Material::Builder()
|
const auto &viewport = _view->getViewport();
|
||||||
.package(GIZMO_GIZMO_DATA, GIZMO_GIZMO_SIZE)
|
|
||||||
.build(*_engine);
|
|
||||||
|
|
||||||
auto vertexCount = 9;
|
auto &tcm = _engine->getTransformManager();
|
||||||
|
auto &rcm = _engine->getRenderableManager();
|
||||||
|
|
||||||
float *vertices = new float[vertexCount * 3]{
|
// Get the projection and view matrices
|
||||||
-0.05, 0.0f, 0.05f,
|
math::mat4 projMatrix = camera.getProjectionMatrix();
|
||||||
0.05f, 0.0f, 0.05f,
|
math::mat4 viewMatrix = camera.getViewMatrix();
|
||||||
0.05f, 0.0f, -0.05f,
|
math::mat4 vpMatrix = projMatrix * viewMatrix;
|
||||||
-0.05f, 0.0f, -0.05f,
|
|
||||||
-0.05f, 1.0f, 0.05f,
|
|
||||||
0.05f, 1.0f, 0.05f,
|
|
||||||
0.05f, 1.0f, -0.05f,
|
|
||||||
-0.05f, 1.0f, -0.05f,
|
|
||||||
0.00f, 1.1f, 0.0f};
|
|
||||||
|
|
||||||
VertexBuffer::BufferDescriptor::Callback vertexCallback = [](void *buf, size_t,
|
auto entity = Entity::import(entityId);
|
||||||
void *data)
|
|
||||||
|
auto renderable = rcm.getInstance(entity);
|
||||||
|
auto worldTransform = tcm.getWorldTransform(tcm.getInstance(entity));
|
||||||
|
|
||||||
|
// Get the axis-aligned bounding box in model space
|
||||||
|
Box aabb = rcm.getAxisAlignedBoundingBox(renderable);
|
||||||
|
|
||||||
|
auto min = aabb.getMin();
|
||||||
|
auto max = aabb.getMax();
|
||||||
|
|
||||||
|
Log("min %f %f %f max %f %f %f", min.x, min.y, min.z, max.x, max.y, max.z);
|
||||||
|
|
||||||
|
// Transform the 8 corners of the AABB to clip space
|
||||||
|
std::array<math::float4, 8> corners = {
|
||||||
|
worldTransform * math::float4(min.x, min.y, min.z, 1.0f),
|
||||||
|
worldTransform * math::float4(max.x, min.y, min.z, 1.0f),
|
||||||
|
worldTransform * math::float4(min.x, max.y, min.z, 1.0f),
|
||||||
|
worldTransform * math::float4(max.x, max.y, min.z, 1.0f),
|
||||||
|
worldTransform * math::float4(min.x, min.y, max.z, 1.0f),
|
||||||
|
worldTransform * math::float4(max.x, min.y, max.z, 1.0f),
|
||||||
|
worldTransform * math::float4(min.x, max.y, max.z, 1.0f),
|
||||||
|
worldTransform * math::float4(max.x, max.y, max.z, 1.0f)};
|
||||||
|
|
||||||
|
// Project corners to clip space and convert to viewport space
|
||||||
|
float minX = std::numeric_limits<float>::max();
|
||||||
|
float minY = std::numeric_limits<float>::max();
|
||||||
|
float maxX = std::numeric_limits<float>::lowest();
|
||||||
|
float maxY = std::numeric_limits<float>::lowest();
|
||||||
|
|
||||||
|
for (const auto &corner : corners)
|
||||||
{
|
{
|
||||||
free((void *)buf);
|
|
||||||
};
|
|
||||||
|
|
||||||
auto indexCount = 42;
|
math::float4 clipSpace = vpMatrix * corner;
|
||||||
uint16_t *indices = new uint16_t[indexCount]{
|
|
||||||
// bottom quad
|
|
||||||
0, 1, 2,
|
|
||||||
0, 2, 3,
|
|
||||||
// top "cone"
|
|
||||||
4, 5, 8,
|
|
||||||
5, 6, 8,
|
|
||||||
4, 7, 8,
|
|
||||||
6, 7, 8,
|
|
||||||
// front
|
|
||||||
0, 1, 4,
|
|
||||||
1, 5, 4,
|
|
||||||
// right
|
|
||||||
1, 2, 5,
|
|
||||||
2, 6, 5,
|
|
||||||
// back
|
|
||||||
2, 6, 7,
|
|
||||||
7, 3, 2,
|
|
||||||
// left
|
|
||||||
0, 4, 7,
|
|
||||||
7, 3, 0
|
|
||||||
|
|
||||||
};
|
// Check if the point is behind the camera
|
||||||
|
if (clipSpace.w <= 0)
|
||||||
|
{
|
||||||
|
continue; // Skip this point
|
||||||
|
}
|
||||||
|
|
||||||
IndexBuffer::BufferDescriptor::Callback indexCallback = [](void *buf, size_t,
|
// Perform perspective division
|
||||||
void *data)
|
math::float3 ndcSpace = clipSpace.xyz / clipSpace.w;
|
||||||
{
|
|
||||||
free((void *)buf);
|
|
||||||
};
|
|
||||||
|
|
||||||
auto vb = VertexBuffer::Builder()
|
// Clamp NDC coordinates to [-1, 1] range
|
||||||
.vertexCount(vertexCount)
|
ndcSpace.x = std::max(-1.0f, std::min(1.0f, ndcSpace.x));
|
||||||
.bufferCount(1)
|
ndcSpace.y = std::max(-1.0f, std::min(1.0f, ndcSpace.y));
|
||||||
.attribute(
|
|
||||||
VertexAttribute::POSITION, 0, VertexBuffer::AttributeType::FLOAT3)
|
|
||||||
.build(*_engine);
|
|
||||||
|
|
||||||
vb->setBufferAt(
|
// Convert NDC to viewport space
|
||||||
*_engine,
|
float viewportX = (ndcSpace.x * 0.5f + 0.5f) * viewport.width;
|
||||||
0,
|
float viewportY = (1.0f - (ndcSpace.y * 0.5f + 0.5f)) * viewport.height; // Flip Y-axis
|
||||||
VertexBuffer::BufferDescriptor(vertices, vb->getVertexCount() * sizeof(filament::math::float3), 0, vertexCallback));
|
|
||||||
|
|
||||||
auto ib = IndexBuffer::Builder().indexCount(indexCount).bufferType(IndexBuffer::IndexType::USHORT).build(*_engine);
|
minX = std::min(minX, viewportX);
|
||||||
ib->setBuffer(*_engine, IndexBuffer::BufferDescriptor(indices, ib->getIndexCount() * sizeof(uint16_t), 0, indexCallback));
|
minY = std::min(minY, viewportY);
|
||||||
|
maxX = std::max(maxX, viewportX);
|
||||||
|
maxY = std::max(maxY, viewportY);
|
||||||
|
}
|
||||||
|
|
||||||
auto &entityManager = EntityManager::get();
|
return Aabb2{minX, minY, maxX, maxY};
|
||||||
|
|
||||||
_gizmo[1] = entityManager.create();
|
|
||||||
_gizmoMaterialInstances[1] = _gizmoMaterial->createInstance();
|
|
||||||
_gizmoMaterialInstances[1]->setParameter("color", math::float3{1.0f, 0.0f, 0.0f});
|
|
||||||
RenderableManager::Builder(1)
|
|
||||||
.boundingBox({{}, {1.0f, 1.0f, 1.0f}})
|
|
||||||
.material(0, _gizmoMaterialInstances[1])
|
|
||||||
.geometry(0, RenderableManager::PrimitiveType::TRIANGLES, vb,
|
|
||||||
ib, 0, indexCount)
|
|
||||||
.culling(false)
|
|
||||||
.build(*_engine, _gizmo[1]);
|
|
||||||
|
|
||||||
_gizmo[0] = entityManager.create();
|
|
||||||
_gizmoMaterialInstances[0] = _gizmoMaterial->createInstance();
|
|
||||||
_gizmoMaterialInstances[0]->setParameter("color", math::float3{0.0f, 1.0f, 0.0f});
|
|
||||||
auto xTransform = math::mat4f::translation(math::float3{0.0f, 0.05f, -0.05f}) * math::mat4f::rotation(-math::F_PI_2, math::float3{0, 0, 1});
|
|
||||||
auto *instanceBufferX = InstanceBuffer::Builder(1).localTransforms(&xTransform).build(*_engine);
|
|
||||||
RenderableManager::Builder(1)
|
|
||||||
.boundingBox({{}, {1.0f, 1.0f, 1.0f}})
|
|
||||||
.instances(1, instanceBufferX)
|
|
||||||
.material(0, _gizmoMaterialInstances[0])
|
|
||||||
.geometry(0, RenderableManager::PrimitiveType::TRIANGLES, vb,
|
|
||||||
ib, 0, indexCount)
|
|
||||||
.culling(false)
|
|
||||||
.build(*_engine, _gizmo[0]);
|
|
||||||
|
|
||||||
_gizmo[2] = entityManager.create();
|
|
||||||
_gizmoMaterialInstances[2] = _gizmoMaterial->createInstance();
|
|
||||||
_gizmoMaterialInstances[2]->setParameter("color", math::float3{0.0f, 0.0f, 1.0f});
|
|
||||||
auto zTransform = math::mat4f::translation(math::float3{0.0f, 0.05f, -0.05f}) * math::mat4f::rotation(3 * math::F_PI_2, math::float3{1, 0, 0});
|
|
||||||
auto *instanceBufferZ = InstanceBuffer::Builder(1).localTransforms(&zTransform).build(*_engine);
|
|
||||||
RenderableManager::Builder(1)
|
|
||||||
.boundingBox({{}, {1.0f, 1.0f, 1.0f}})
|
|
||||||
.instances(1, instanceBufferZ)
|
|
||||||
.material(0, _gizmoMaterialInstances[2])
|
|
||||||
.geometry(0, RenderableManager::PrimitiveType::TRIANGLES, vb,
|
|
||||||
ib, 0, indexCount)
|
|
||||||
.culling(false)
|
|
||||||
.build(*_engine, _gizmo[2]);
|
|
||||||
|
|
||||||
auto &rm = _engine->getRenderableManager();
|
|
||||||
rm.setPriority(rm.getInstance(_gizmo[0]), 7);
|
|
||||||
rm.setPriority(rm.getInstance(_gizmo[1]), 7);
|
|
||||||
rm.setPriority(rm.getInstance(_gizmo[2]), 7);
|
|
||||||
return Entity::smuggle(_gizmo[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneManager::getGizmo(EntityId *out)
|
void SceneManager::getGizmo(EntityId *out)
|
||||||
{
|
{
|
||||||
out[0] = Entity::smuggle(_gizmo[0]);
|
out[0] = Entity::smuggle(_gizmo->x());
|
||||||
out[1] = Entity::smuggle(_gizmo[1]);
|
out[1] = Entity::smuggle(_gizmo->y());
|
||||||
out[2] = Entity::smuggle(_gizmo[2]);
|
out[2] = Entity::smuggle(_gizmo->z());
|
||||||
|
out[3] = Entity::smuggle(_gizmo->center());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace thermion_filament
|
} // namespace thermion_filament
|
||||||
|
|||||||
@@ -822,9 +822,9 @@ extern "C"
|
|||||||
return ((SceneManager *)sceneManager)->getParent(child);
|
return ((SceneManager *)sceneManager)->getParent(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void set_parent(void *const sceneManager, EntityId child, EntityId parent)
|
EMSCRIPTEN_KEEPALIVE void set_parent(void *const sceneManager, EntityId child, EntityId parent, bool preserveScaling)
|
||||||
{
|
{
|
||||||
((SceneManager *)sceneManager)->setParent(child, parent);
|
((SceneManager *)sceneManager)->setParent(child, parent, preserveScaling);
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE void test_collisions(void *const sceneManager, EntityId entity)
|
EMSCRIPTEN_KEEPALIVE void test_collisions(void *const sceneManager, EntityId entity)
|
||||||
@@ -841,4 +841,10 @@ extern "C"
|
|||||||
{
|
{
|
||||||
return ((SceneManager *)sceneManager)->getGizmo(out);
|
return ((SceneManager *)sceneManager)->getGizmo(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE Aabb2 get_bounding_box(void *const sceneManager, EntityId entity) {
|
||||||
|
return ((SceneManager *)sceneManager)->getBoundingBox(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ add_executable(${MODULE_NAME}
|
|||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../src/FilamentViewer.cpp"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../src/FilamentViewer.cpp"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../src/ThermionDartApi.cpp"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../src/ThermionDartApi.cpp"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../src/ThermionDartFFIApi.cpp"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../src/ThermionDartFFIApi.cpp"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/../src/Gizmo.cpp"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../src/StreamBufferAdapter.cpp"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../src/StreamBufferAdapter.cpp"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../src/TimeIt.cpp"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../src/TimeIt.cpp"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../src/camutils/Manipulator.cpp"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../src/camutils/Manipulator.cpp"
|
||||||
|
|||||||
Reference in New Issue
Block a user