internal: store bounding box with SceneAsset rather than recalculating from renderables
This commit is contained in:
@@ -4,9 +4,9 @@ import 'package:thermion_dart/src/viewer/src/ffi/src/callbacks.dart';
|
|||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_material.dart';
|
import 'package:thermion_dart/src/viewer/src/ffi/src/ffi_material.dart';
|
||||||
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_viewer_ffi.dart';
|
import 'package:thermion_dart/src/viewer/src/ffi/src/thermion_viewer_ffi.dart';
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
|
import 'package:vector_math/vector_math_64.dart' as v64;
|
||||||
|
|
||||||
class FFIAsset extends ThermionAsset {
|
class FFIAsset extends ThermionAsset {
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@@ -236,16 +236,25 @@ class FFIAsset extends ThermionAsset {
|
|||||||
|
|
||||||
FFIAsset? boundingBoxAsset;
|
FFIAsset? boundingBoxAsset;
|
||||||
|
|
||||||
Future<Aabb3> getBoundingBox() async {
|
Future<v64.Aabb3> getBoundingBox() async {
|
||||||
late ThermionEntity targetEntity;
|
final entities = <ThermionEntity>[];
|
||||||
if (RenderableManager_isRenderable(renderableManager, entity)) {
|
if (RenderableManager_isRenderable(renderableManager, entity)) {
|
||||||
targetEntity = entity;
|
entities.add(entity);
|
||||||
} else {
|
} else {
|
||||||
targetEntity = (await getChildEntities()).first;
|
entities.addAll(await getChildEntities());
|
||||||
}
|
}
|
||||||
final aabb3 =
|
|
||||||
SceneManager_getRenderableBoundingBox(sceneManager, targetEntity);
|
var boundingBox = v64.Aabb3();
|
||||||
return aabb3;
|
|
||||||
|
for (final entity in entities) {
|
||||||
|
final aabb3 = SceneManager_getRenderableBoundingBox(sceneManager, entity);
|
||||||
|
final entityBB = v64.Aabb3.centerAndHalfExtents(
|
||||||
|
v64.Vector3(aabb3.centerX, aabb3.centerY, aabb3.centerZ),
|
||||||
|
v64.Vector3(aabb3.halfExtentX, aabb3.halfExtentY, aabb3.halfExtentZ),
|
||||||
|
);
|
||||||
|
boundingBox.hull(entityBB);
|
||||||
|
}
|
||||||
|
return boundingBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -254,7 +263,8 @@ class FFIAsset extends ThermionAsset {
|
|||||||
@override
|
@override
|
||||||
Future<void> setBoundingBoxVisibility(bool visible) async {
|
Future<void> setBoundingBoxVisibility(bool visible) async {
|
||||||
if (boundingBoxAsset == null) {
|
if (boundingBoxAsset == null) {
|
||||||
final boundingBox = await getBoundingBox();
|
final boundingBox = await SceneAsset_getBoundingBox(pointer!);
|
||||||
|
|
||||||
final min = [
|
final min = [
|
||||||
boundingBox.centerX - boundingBox.halfExtentX,
|
boundingBox.centerX - boundingBox.halfExtentX,
|
||||||
boundingBox.centerY - boundingBox.halfExtentY,
|
boundingBox.centerY - boundingBox.halfExtentY,
|
||||||
|
|||||||
@@ -1718,7 +1718,7 @@ external void SceneManager_destroyLightsRenderThread(
|
|||||||
);
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
EntityId Function(
|
ffi.Void Function(
|
||||||
ffi.Pointer<TSceneManager>,
|
ffi.Pointer<TSceneManager>,
|
||||||
ffi.Uint8,
|
ffi.Uint8,
|
||||||
ffi.Float,
|
ffi.Float,
|
||||||
@@ -1738,7 +1738,7 @@ external void SceneManager_destroyLightsRenderThread(
|
|||||||
ffi.Bool,
|
ffi.Bool,
|
||||||
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(EntityId)>>)>(
|
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(EntityId)>>)>(
|
||||||
isLeaf: true)
|
isLeaf: true)
|
||||||
external int SceneManager_addLightRenderThread(
|
external void SceneManager_addLightRenderThread(
|
||||||
ffi.Pointer<TSceneManager> tSceneManager,
|
ffi.Pointer<TSceneManager> tSceneManager,
|
||||||
int type,
|
int type,
|
||||||
double colour,
|
double colour,
|
||||||
@@ -2383,6 +2383,11 @@ external ffi.Pointer<TSceneAsset> SceneAsset_createInstance(
|
|||||||
int materialInstanceCount,
|
int materialInstanceCount,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<Aabb3 Function(ffi.Pointer<TSceneAsset>)>(isLeaf: true)
|
||||||
|
external Aabb3 SceneAsset_getBoundingBox(
|
||||||
|
ffi.Pointer<TSceneAsset> asset,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<ffi.Void Function(ffi.Pointer<TAnimationManager>, EntityId)>(
|
@ffi.Native<ffi.Void Function(ffi.Pointer<TAnimationManager>, EntityId)>(
|
||||||
isLeaf: true)
|
isLeaf: true)
|
||||||
external void AnimationManager_addAnimationComponent(
|
external void AnimationManager_addAnimationComponent(
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ extern "C"
|
|||||||
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneAsset_getInstance(TSceneAsset *tSceneAsset, int index);
|
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneAsset_getInstance(TSceneAsset *tSceneAsset, int index);
|
||||||
EMSCRIPTEN_KEEPALIVE size_t SceneAsset_getInstanceCount(TSceneAsset *tSceneAsset);
|
EMSCRIPTEN_KEEPALIVE size_t SceneAsset_getInstanceCount(TSceneAsset *tSceneAsset);
|
||||||
EMSCRIPTEN_KEEPALIVE TSceneAsset * SceneAsset_createInstance(TSceneAsset *asset, TMaterialInstance **materialInstances, int materialInstanceCount);
|
EMSCRIPTEN_KEEPALIVE TSceneAsset * SceneAsset_createInstance(TSceneAsset *asset, TMaterialInstance **materialInstances, int materialInstanceCount);
|
||||||
|
EMSCRIPTEN_KEEPALIVE Aabb3 SceneAsset_getBoundingBox(TSceneAsset *asset);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,6 +122,10 @@ namespace thermion
|
|||||||
return Entity(); // not currently implemented
|
return Entity(); // not currently implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const filament::Aabb getBoundingBox() const override {
|
||||||
|
return _boundingBox;
|
||||||
|
}
|
||||||
|
|
||||||
static std::unique_ptr<GeometrySceneAsset> create(
|
static std::unique_ptr<GeometrySceneAsset> create(
|
||||||
float *vertices, uint32_t numVertices,
|
float *vertices, uint32_t numVertices,
|
||||||
float *normals, uint32_t numNormals,
|
float *normals, uint32_t numNormals,
|
||||||
@@ -136,7 +140,7 @@ namespace thermion
|
|||||||
VertexBuffer *_vertexBuffer = nullptr;
|
VertexBuffer *_vertexBuffer = nullptr;
|
||||||
IndexBuffer *_indexBuffer = nullptr;
|
IndexBuffer *_indexBuffer = nullptr;
|
||||||
std::vector<MaterialInstance*> _materialInstances;
|
std::vector<MaterialInstance*> _materialInstances;
|
||||||
Box _boundingBox;
|
Aabb _boundingBox;
|
||||||
GeometrySceneAsset *_instanceOwner = std::nullptr_t();
|
GeometrySceneAsset *_instanceOwner = std::nullptr_t();
|
||||||
utils::Entity _entity;
|
utils::Entity _entity;
|
||||||
RenderableManager::PrimitiveType _primitiveType;
|
RenderableManager::PrimitiveType _primitiveType;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <utils/Entity.h>
|
#include <utils/Entity.h>
|
||||||
|
#include <filament/Box.h>
|
||||||
#include <filament/Engine.h>
|
#include <filament/Engine.h>
|
||||||
#include <filament/Material.h>
|
#include <filament/Material.h>
|
||||||
#include <filament/MaterialInstance.h>
|
#include <filament/MaterialInstance.h>
|
||||||
@@ -145,6 +146,10 @@ namespace thermion
|
|||||||
|
|
||||||
math::mat4f getRotationForAxis(Gizmo::Axis axis);
|
math::mat4f getRotationForAxis(Gizmo::Axis axis);
|
||||||
|
|
||||||
|
const filament::Aabb getBoundingBox() const override {
|
||||||
|
return _boundingBox;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SceneAsset *_source;
|
SceneAsset *_source;
|
||||||
Engine *_engine;
|
Engine *_engine;
|
||||||
@@ -161,6 +166,8 @@ namespace thermion
|
|||||||
std::vector<utils::Entity> _entities;
|
std::vector<utils::Entity> _entities;
|
||||||
std::vector<MaterialInstance *> _materialInstances;
|
std::vector<MaterialInstance *> _materialInstances;
|
||||||
|
|
||||||
|
filament::Aabb _boundingBox;
|
||||||
|
|
||||||
GizmoPickResultType getPickResult(utils::Entity entity)
|
GizmoPickResultType getPickResult(utils::Entity entity)
|
||||||
{
|
{
|
||||||
if (entity.isNull())
|
if (entity.isNull())
|
||||||
|
|||||||
@@ -167,6 +167,10 @@ namespace thermion
|
|||||||
return entities[0];
|
return entities[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const filament::Aabb getBoundingBox() const override {
|
||||||
|
return _asset->getBoundingBox();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
gltfio::FilamentAsset *_asset;
|
gltfio::FilamentAsset *_asset;
|
||||||
gltfio::AssetLoader *_assetLoader;
|
gltfio::AssetLoader *_assetLoader;
|
||||||
|
|||||||
@@ -159,7 +159,9 @@ namespace thermion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const filament::Aabb getBoundingBox() const override {
|
||||||
|
return _instance->getBoundingBox();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
filament::Engine *_engine;
|
filament::Engine *_engine;
|
||||||
|
|||||||
@@ -48,6 +48,10 @@ public:
|
|||||||
const Entity* getChildEntities() override;
|
const Entity* getChildEntities() override;
|
||||||
Entity findEntityByName(const char* name) override;
|
Entity findEntityByName(const char* name) override;
|
||||||
|
|
||||||
|
const filament::Aabb getBoundingBox() const override {
|
||||||
|
return filament::Aabb();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Engine& _engine;
|
Engine& _engine;
|
||||||
utils::Entity _gridEntity;
|
utils::Entity _gridEntity;
|
||||||
|
|||||||
@@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <utils/Entity.h>
|
|
||||||
#include <gltfio/FilamentAsset.h>
|
|
||||||
#include <filament/Scene.h>
|
#include <filament/Scene.h>
|
||||||
|
|
||||||
|
#include <gltfio/FilamentAsset.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <utils/Entity.h>
|
||||||
|
|
||||||
#include "CustomGeometry.hpp"
|
#include "CustomGeometry.hpp"
|
||||||
#include "Log.hpp"
|
#include "Log.hpp"
|
||||||
|
|
||||||
@@ -51,6 +53,8 @@ class SceneAsset {
|
|||||||
virtual void setPriority(RenderableManager& rm, int mask) = 0;
|
virtual void setPriority(RenderableManager& rm, int mask) = 0;
|
||||||
virtual void setLayer(RenderableManager& rm, int layer) = 0;
|
virtual void setLayer(RenderableManager& rm, int layer) = 0;
|
||||||
|
|
||||||
|
virtual const filament::Aabb getBoundingBox() const = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -101,6 +101,12 @@ extern "C"
|
|||||||
return reinterpret_cast<TSceneAsset *>(instance);
|
return reinterpret_cast<TSceneAsset *>(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE Aabb3 SceneAsset_getBoundingBox(TSceneAsset *tSceneAsset) {
|
||||||
|
auto *asset = reinterpret_cast<SceneAsset*>(tSceneAsset);
|
||||||
|
auto box = asset->getBoundingBox();
|
||||||
|
return Aabb3{box.center().x, box.center().y, box.center().z, box.extent().x, box.extent().y, box.extent().z};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ namespace thermion
|
|||||||
_vertexBuffer(vertexBuffer),
|
_vertexBuffer(vertexBuffer),
|
||||||
_indexBuffer(indexBuffer),
|
_indexBuffer(indexBuffer),
|
||||||
_primitiveType(primitiveType),
|
_primitiveType(primitiveType),
|
||||||
_boundingBox(boundingBox),
|
|
||||||
_instanceOwner(instanceOwner)
|
_instanceOwner(instanceOwner)
|
||||||
{
|
{
|
||||||
_materialInstances.insert(_materialInstances.begin(), materialInstances, materialInstances + materialInstanceCount);
|
_materialInstances.insert(_materialInstances.begin(), materialInstances, materialInstances + materialInstanceCount);
|
||||||
@@ -39,11 +38,15 @@ namespace thermion
|
|||||||
_entity = utils::EntityManager::get().create();
|
_entity = utils::EntityManager::get().create();
|
||||||
|
|
||||||
RenderableManager::Builder builder(1);
|
RenderableManager::Builder builder(1);
|
||||||
builder.boundingBox(_boundingBox)
|
builder.boundingBox(boundingBox)
|
||||||
.geometry(0, _primitiveType, _vertexBuffer, _indexBuffer)
|
.geometry(0, _primitiveType, _vertexBuffer, _indexBuffer)
|
||||||
.culling(true)
|
.culling(true)
|
||||||
.receiveShadows(true)
|
.receiveShadows(true)
|
||||||
.castShadows(true);
|
.castShadows(true);
|
||||||
|
|
||||||
|
_boundingBox.min = boundingBox.getMin();
|
||||||
|
_boundingBox.max = boundingBox.getMax();
|
||||||
|
|
||||||
for (int i = 0; i < materialInstanceCount; i++)
|
for (int i = 0; i < materialInstanceCount; i++)
|
||||||
{
|
{
|
||||||
builder.material(i, materialInstances[i]);
|
builder.material(i, materialInstances[i]);
|
||||||
@@ -83,7 +86,7 @@ namespace thermion
|
|||||||
materialInstances,
|
materialInstances,
|
||||||
materialInstanceCount,
|
materialInstanceCount,
|
||||||
_primitiveType,
|
_primitiveType,
|
||||||
_boundingBox,
|
filament::Box().set(_boundingBox.min, _boundingBox.max),
|
||||||
this);
|
this);
|
||||||
auto *raw = instance.get();
|
auto *raw = instance.get();
|
||||||
_instances.push_back(std::move(instance));
|
_instances.push_back(std::move(instance));
|
||||||
|
|||||||
@@ -26,7 +26,10 @@ namespace thermion
|
|||||||
}
|
}
|
||||||
TRACE("Creating instance %d", instanceNumber);
|
TRACE("Creating instance %d", instanceNumber);
|
||||||
auto instance = _asset->getAssetInstances()[instanceNumber];
|
auto instance = _asset->getAssetInstances()[instanceNumber];
|
||||||
|
|
||||||
instance->recomputeBoundingBoxes();
|
instance->recomputeBoundingBoxes();
|
||||||
|
auto bb = instance->getBoundingBox();
|
||||||
|
TRACE("Instance bounding box center (%f,%f,%f), extent (%f,%f,%f)", bb.center().x, bb.center().y, bb.center().z, bb.extent().x,bb.extent().y,bb.extent().z);
|
||||||
instance->getAnimator()->updateBoneMatrices();
|
instance->getAnimator()->updateBoneMatrices();
|
||||||
|
|
||||||
auto& rm = _engine->getRenderableManager();
|
auto& rm = _engine->getRenderableManager();
|
||||||
|
|||||||
Reference in New Issue
Block a user