expose method for retrieving all child entities
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
@@ -129,7 +130,7 @@ class ExampleWidgetState extends State<ExampleWidget> {
|
|||||||
),
|
),
|
||||||
EntityListWidget(controller: _filamentController),
|
EntityListWidget(controller: _filamentController),
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: 0,
|
bottom: Platform.isIOS ? 30 : 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
right: 10,
|
right: 10,
|
||||||
height: 30,
|
height: 30,
|
||||||
@@ -164,9 +165,8 @@ class ExampleWidgetState extends State<ExampleWidget> {
|
|||||||
),
|
),
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await _filamentController!.loadGlb(
|
await _filamentController!
|
||||||
'assets/shapes/shapes.glb',
|
.loadGlb('assets/shapes/shapes.glb', numInstances: 1);
|
||||||
numInstances: 10);
|
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
|
|||||||
@@ -215,6 +215,13 @@ class _AssetSubmenuState extends State<AssetSubmenu> {
|
|||||||
},
|
},
|
||||||
child: const Text("Add point light"),
|
child: const Text("Add point light"),
|
||||||
),
|
),
|
||||||
|
MenuItemButton(
|
||||||
|
onPressed: () async {
|
||||||
|
await widget.controller
|
||||||
|
.addLight(3, 6500, 15000000, 0, 1, 0, 0, -1, 0, true);
|
||||||
|
},
|
||||||
|
child: const Text("Add spot light"),
|
||||||
|
),
|
||||||
MenuItemButton(
|
MenuItemButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await widget.controller.clearLights();
|
await widget.controller.clearLights();
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ namespace flutter_filament
|
|||||||
uint32_t _imageWidth = 0;
|
uint32_t _imageWidth = 0;
|
||||||
mat4f _imageScale;
|
mat4f _imageScale;
|
||||||
Texture *_imageTexture = nullptr;
|
Texture *_imageTexture = nullptr;
|
||||||
utils::Entity *_imageEntity = nullptr;
|
utils::Entity _imageEntity;
|
||||||
VertexBuffer *_imageVb = nullptr;
|
VertexBuffer *_imageVb = nullptr;
|
||||||
IndexBuffer *_imageIb = nullptr;
|
IndexBuffer *_imageIb = nullptr;
|
||||||
Material *_imageMaterial = nullptr;
|
Material *_imageMaterial = nullptr;
|
||||||
|
|||||||
@@ -188,6 +188,7 @@ extern "C"
|
|||||||
FLUTTER_PLUGIN_EXPORT const char *get_name_for_entity(void *const sceneManager, const EntityId entityId);
|
FLUTTER_PLUGIN_EXPORT const char *get_name_for_entity(void *const sceneManager, const EntityId entityId);
|
||||||
FLUTTER_PLUGIN_EXPORT EntityId find_child_entity_by_name(void *const sceneManager, const EntityId parent, const char* name);
|
FLUTTER_PLUGIN_EXPORT EntityId find_child_entity_by_name(void *const sceneManager, const EntityId parent, const char* name);
|
||||||
FLUTTER_PLUGIN_EXPORT int get_entity_count(void *const sceneManager, const EntityId target, bool renderableOnly);
|
FLUTTER_PLUGIN_EXPORT int get_entity_count(void *const sceneManager, const EntityId target, bool renderableOnly);
|
||||||
|
FLUTTER_PLUGIN_EXPORT void get_entities(void *const sceneManager, const EntityId target, bool renderableOnly, EntityId* out);
|
||||||
FLUTTER_PLUGIN_EXPORT const char* get_entity_name_at(void *const sceneManager, const EntityId target, int index, bool renderableOnly);
|
FLUTTER_PLUGIN_EXPORT const char* get_entity_name_at(void *const sceneManager, const EntityId target, int index, bool renderableOnly);
|
||||||
FLUTTER_PLUGIN_EXPORT void set_recording(void *const viewer, bool recording);
|
FLUTTER_PLUGIN_EXPORT void set_recording(void *const viewer, bool recording);
|
||||||
FLUTTER_PLUGIN_EXPORT void set_recording_output_directory(void *const viewer, const char* outputDirectory);
|
FLUTTER_PLUGIN_EXPORT void set_recording_output_directory(void *const viewer, const char* outputDirectory);
|
||||||
|
|||||||
@@ -130,6 +130,7 @@ namespace flutter_filament
|
|||||||
EntityId entityId,
|
EntityId entityId,
|
||||||
const char *entityName);
|
const char *entityName);
|
||||||
int getEntityCount(EntityId entity, bool renderableOnly);
|
int getEntityCount(EntityId entity, bool renderableOnly);
|
||||||
|
void getEntities(EntityId entity, bool renderableOnly, EntityId *out);
|
||||||
const char* getEntityNameAt(EntityId entity, int index, bool renderableOnly);
|
const char* getEntityNameAt(EntityId entity, int index, bool renderableOnly);
|
||||||
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);
|
||||||
|
|||||||
@@ -238,17 +238,16 @@ namespace flutter_filament
|
|||||||
_imageIb->setBuffer(*_engine, {sFullScreenTriangleIndices,
|
_imageIb->setBuffer(*_engine, {sFullScreenTriangleIndices,
|
||||||
sizeof(sFullScreenTriangleIndices)});
|
sizeof(sFullScreenTriangleIndices)});
|
||||||
|
|
||||||
utils::Entity imageEntity = em.create();
|
_imageEntity = em.create();
|
||||||
RenderableManager::Builder(1)
|
RenderableManager::Builder(1)
|
||||||
.boundingBox({{}, {1.0f, 1.0f, 1.0f}})
|
.boundingBox({{}, {1.0f, 1.0f, 1.0f}})
|
||||||
.material(0, _imageMaterial->getDefaultInstance())
|
.material(0, _imageMaterial->getDefaultInstance())
|
||||||
.geometry(0, RenderableManager::PrimitiveType::TRIANGLES, _imageVb,
|
.geometry(0, RenderableManager::PrimitiveType::TRIANGLES, _imageVb,
|
||||||
_imageIb, 0, 3)
|
_imageIb, 0, 3)
|
||||||
.culling(false)
|
.culling(false)
|
||||||
.build(*_engine, imageEntity);
|
.build(*_engine, _imageEntity);
|
||||||
_imageEntity = &imageEntity;
|
_scene->addEntity(_imageEntity);
|
||||||
_scene->addEntity(imageEntity);
|
Log("Added imageEntity %d", _imageEntity);
|
||||||
Log("Added imageEntity %d", imageEntity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FilamentViewer::setAntiAliasing(bool msaa, bool fxaa, bool taa) {
|
void FilamentViewer::setAntiAliasing(bool msaa, bool fxaa, bool taa) {
|
||||||
@@ -335,6 +334,8 @@ namespace flutter_filament
|
|||||||
_lights.push_back(light);
|
_lights.push_back(light);
|
||||||
|
|
||||||
auto entityId = Entity::smuggle(light);
|
auto entityId = Entity::smuggle(light);
|
||||||
|
auto transformInstance = transformManager.getInstance(light);
|
||||||
|
transformManager.setTransform(transformInstance, math::mat4::translation(math::float3 { posX, posY, posZ}));
|
||||||
Log("Added light under entity ID %d of type %d with colour %f intensity %f at (%f, %f, %f) with direction (%f, %f, %f) with shadows %d", entityId, t, colour, intensity, posX, posY, posZ, dirX, dirY, dirZ, shadows);
|
Log("Added light under entity ID %d of type %d with colour %f intensity %f at (%f, %f, %f) with direction (%f, %f, %f) with shadows %d", entityId, t, colour, intensity, posX, posY, posZ, dirX, dirY, dirZ, shadows);
|
||||||
return entityId;
|
return entityId;
|
||||||
}
|
}
|
||||||
@@ -885,7 +886,7 @@ namespace flutter_filament
|
|||||||
|
|
||||||
ResourceBuffer skyboxBuffer = _resourceLoaderWrapper->load(skyboxPath);
|
ResourceBuffer skyboxBuffer = _resourceLoaderWrapper->load(skyboxPath);
|
||||||
|
|
||||||
// because this will go out of scope before the texture callback is invoked, we need to make a copy to the heap
|
// because this will go out of scope before the texture callback is invoked, we need to make a copy of the variable itself (not its contents)
|
||||||
ResourceBuffer *skyboxBufferCopy = new ResourceBuffer(skyboxBuffer);
|
ResourceBuffer *skyboxBufferCopy = new ResourceBuffer(skyboxBuffer);
|
||||||
|
|
||||||
if (skyboxBuffer.size <= 0)
|
if (skyboxBuffer.size <= 0)
|
||||||
@@ -1449,9 +1450,12 @@ namespace flutter_filament
|
|||||||
|
|
||||||
void FilamentViewer::pick(uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y))
|
void FilamentViewer::pick(uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y))
|
||||||
{
|
{
|
||||||
|
|
||||||
_view->pick(x, y, [=](filament::View::PickingQueryResult const &result)
|
_view->pick(x, y, [=](filament::View::PickingQueryResult const &result)
|
||||||
{
|
{
|
||||||
callback(Entity::smuggle(result.renderable), x, y);
|
if(result.renderable != _imageEntity) {
|
||||||
|
callback(Entity::smuggle(result.renderable), x, y);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -562,6 +562,10 @@ extern "C"
|
|||||||
return ((SceneManager *)sceneManager)->getEntityCount(target, renderableOnly);
|
return ((SceneManager *)sceneManager)->getEntityCount(target, renderableOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FLUTTER_PLUGIN_EXPORT void get_entities(void *const sceneManager, const EntityId target, bool renderableOnly, EntityId* out) {
|
||||||
|
((SceneManager *)sceneManager)->getEntities(target, renderableOnly, out);
|
||||||
|
}
|
||||||
|
|
||||||
FLUTTER_PLUGIN_EXPORT const char* get_entity_name_at(void *const sceneManager, const EntityId target, int index, bool renderableOnly) {
|
FLUTTER_PLUGIN_EXPORT const char* get_entity_name_at(void *const sceneManager, const EntityId target, int index, bool renderableOnly) {
|
||||||
return ((SceneManager *)sceneManager)->getEntityNameAt(target, index, renderableOnly);
|
return ((SceneManager *)sceneManager)->getEntityNameAt(target, index, renderableOnly);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1529,6 +1529,34 @@ namespace flutter_filament
|
|||||||
return instance->getEntityCount();
|
return instance->getEntityCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SceneManager::getEntities(EntityId entityId, bool renderableOnly, EntityId* out) {
|
||||||
|
const auto *instance = getInstanceByEntityId(entityId);
|
||||||
|
if(!instance) {
|
||||||
|
auto asset = getAssetByEntityId(entityId);
|
||||||
|
if(asset) {
|
||||||
|
instance = asset->getInstance();
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(renderableOnly) {
|
||||||
|
int count = 0;
|
||||||
|
const auto& rm = _engine->getRenderableManager();
|
||||||
|
const Entity *entities = instance->getEntities();
|
||||||
|
int offset = 0;
|
||||||
|
for(int i=0; i < instance->getEntityCount(); i++) {
|
||||||
|
if(rm.hasComponent(entities[i])) {
|
||||||
|
out[offset] = Entity::smuggle(entities[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(int i=0;i < instance->getEntityCount(); i++) {
|
||||||
|
out[i] = Entity::smuggle(instance->getEntities()[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const char* SceneManager::getEntityNameAt(EntityId entityId, int index, bool renderableOnly) {
|
const char* SceneManager::getEntityNameAt(EntityId entityId, int index, bool renderableOnly) {
|
||||||
const auto *instance = getInstanceByEntityId(entityId);
|
const auto *instance = getInstanceByEntityId(entityId);
|
||||||
if(!instance) {
|
if(!instance) {
|
||||||
|
|||||||
@@ -65,6 +65,9 @@ class Gizmo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void detach() async {
|
void detach() async {
|
||||||
|
await controller.setParent(x, 0);
|
||||||
|
await controller.setParent(y, 0);
|
||||||
|
await controller.setParent(z, 0);
|
||||||
await controller.hide(x, null);
|
await controller.hide(x, null);
|
||||||
await controller.hide(y, null);
|
await controller.hide(y, null);
|
||||||
await controller.hide(z, null);
|
await controller.hide(z, null);
|
||||||
|
|||||||
@@ -576,6 +576,12 @@ abstract class FilamentController {
|
|||||||
double orbitSpeedY = 0.01,
|
double orbitSpeedY = 0.01,
|
||||||
double zoomSpeed = 0.01});
|
double zoomSpeed = 0.01});
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns all child entities under [parent].
|
||||||
|
///
|
||||||
|
Future<List<FilamentEntity>> getChildEntities(
|
||||||
|
FilamentEntity parent, bool renderableOnly);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Finds the child entity named [childName] associated with the given parent.
|
/// Finds the child entity named [childName] associated with the given parent.
|
||||||
/// Usually, [parent] will be the return value from [loadGlb]/[loadGltf] and [childName] will be the name of a node/mesh.
|
/// Usually, [parent] will be the return value from [loadGlb]/[loadGltf] and [childName] will be the name of a node/mesh.
|
||||||
@@ -584,9 +590,9 @@ abstract class FilamentController {
|
|||||||
FilamentEntity parent, String childName);
|
FilamentEntity parent, String childName);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// List all child entities under the given entity.
|
/// List the name of all child entities under the given entity.
|
||||||
///
|
///
|
||||||
Future<List<String>> getChildEntities(FilamentEntity entity,
|
Future<List<String>> getChildEntityNames(FilamentEntity entity,
|
||||||
{bool renderableOnly = true});
|
{bool renderableOnly = true});
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -358,7 +358,7 @@ class FilamentControllerFFI extends FilamentController {
|
|||||||
get_gizmo(_sceneManager!, out);
|
get_gizmo(_sceneManager!, out);
|
||||||
var gizmo = Gizmo(out[0], out[1], out[2], this);
|
var gizmo = Gizmo(out[0], out[1], out[2], this);
|
||||||
allocator.free(out);
|
allocator.free(out);
|
||||||
_scene = SceneImpl(gizmo);
|
_scene = SceneImpl(gizmo, this);
|
||||||
|
|
||||||
hasViewer.value = true;
|
hasViewer.value = true;
|
||||||
_creating = false;
|
_creating = false;
|
||||||
@@ -1504,8 +1504,19 @@ class FilamentControllerFFI extends FilamentController {
|
|||||||
return childEntity;
|
return childEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<List<FilamentEntity>> getChildEntities(
|
||||||
|
FilamentEntity parent, bool renderableOnly) async {
|
||||||
|
var count = get_entity_count(_sceneManager!, parent, renderableOnly);
|
||||||
|
var out = allocator<Int32>(count);
|
||||||
|
get_entities(_sceneManager!, parent, renderableOnly, out);
|
||||||
|
var outList =
|
||||||
|
List.generate(count, (index) => out[index]).cast<FilamentEntity>();
|
||||||
|
allocator.free(out);
|
||||||
|
return outList;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<String>> getChildEntities(FilamentEntity entity,
|
Future<List<String>> getChildEntityNames(FilamentEntity entity,
|
||||||
{bool renderableOnly = false}) async {
|
{bool renderableOnly = false}) async {
|
||||||
var count = get_entity_count(_sceneManager!, entity, renderableOnly);
|
var count = get_entity_count(_sceneManager!, entity, renderableOnly);
|
||||||
var names = <String>[];
|
var names = <String>[];
|
||||||
|
|||||||
@@ -885,6 +885,17 @@ external int get_entity_count(
|
|||||||
bool renderableOnly,
|
bool renderableOnly,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Void Function(
|
||||||
|
ffi.Pointer<ffi.Void>, EntityId, ffi.Bool, ffi.Pointer<EntityId>)>(
|
||||||
|
symbol: 'get_entities', assetId: 'flutter_filament_plugin')
|
||||||
|
external void get_entities(
|
||||||
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
|
int target,
|
||||||
|
bool renderableOnly,
|
||||||
|
ffi.Pointer<EntityId> out,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Pointer<ffi.Char> Function(
|
ffi.Pointer<ffi.Char> Function(
|
||||||
ffi.Pointer<ffi.Void>, EntityId, ffi.Int, ffi.Bool)>(
|
ffi.Pointer<ffi.Void>, EntityId, ffi.Int, ffi.Bool)>(
|
||||||
|
|||||||
@@ -9,7 +9,9 @@ class SceneImpl extends Scene {
|
|||||||
final Gizmo _gizmo;
|
final Gizmo _gizmo;
|
||||||
Gizmo get gizmo => _gizmo;
|
Gizmo get gizmo => _gizmo;
|
||||||
|
|
||||||
SceneImpl(this._gizmo);
|
FilamentController controller;
|
||||||
|
|
||||||
|
SceneImpl(this._gizmo, this.controller);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FilamentEntity? selected;
|
FilamentEntity? selected;
|
||||||
@@ -35,8 +37,9 @@ class SceneImpl extends Scene {
|
|||||||
_onUpdatedController.add(true);
|
_onUpdatedController.add(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unregisterLight(FilamentEntity entity) {
|
void unregisterLight(FilamentEntity entity) async {
|
||||||
if (selected == entity) {
|
var children = await controller.getChildEntities(entity, true);
|
||||||
|
if (selected == entity || children.contains(selected)) {
|
||||||
selected = null;
|
selected = null;
|
||||||
_gizmo.detach();
|
_gizmo.detach();
|
||||||
}
|
}
|
||||||
@@ -45,8 +48,9 @@ class SceneImpl extends Scene {
|
|||||||
_onUpdatedController.add(true);
|
_onUpdatedController.add(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unregisterEntity(FilamentEntity entity) {
|
void unregisterEntity(FilamentEntity entity) async {
|
||||||
if (selected == entity) {
|
var children = await controller.getChildEntities(entity, true);
|
||||||
|
if (selected == entity || children.contains(selected)) {
|
||||||
selected = null;
|
selected = null;
|
||||||
_gizmo.detach();
|
_gizmo.detach();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user