feature!:
This is a breaking change needed to fully implement instancing and stencil highlighting.
Previously, users would work directly with entities (on the Dart side, ThermionEntity), e.g.
final entity = await viewer.loadGlb("some.glb");
However, Filament "entities" are a lower-level abstraction.
Loading a glTF file, for example, inserts multiple entities into the scene.
For example, each mesh, light, and camera within a glTF asset will be assigned an entity. A top-level (non-renderable) entity will also be created for the glTF asset, which can be used to transform the entire hierarchy.
"Asset" is a better representation for loading/inserting objects into the scene; think of this as a bundle of entities.
Unless you need to work directly with transforms, instancing, materials and renderables, you can work directly with ThermionAsset.
This commit is contained in:
155
thermion_dart/native/src/c_api/TTransformManager.cpp
Normal file
155
thermion_dart/native/src/c_api/TTransformManager.cpp
Normal file
@@ -0,0 +1,155 @@
|
||||
#include <utils/Entity.h>
|
||||
#include <filament/TransformManager.h>
|
||||
#include <filament/math/mat4.h>
|
||||
#include <gltfio/math.h>
|
||||
|
||||
#include "c_api/APIExport.h"
|
||||
#include "MathUtils.hpp"
|
||||
#include "Log.hpp"
|
||||
|
||||
using namespace thermion;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
using namespace filament;
|
||||
using namespace utils;
|
||||
using namespace filament::gltfio;
|
||||
|
||||
#include "c_api/TTransformManager.h"
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE double4x4 TransformManager_getLocalTransform(TTransformManager *tTransformManager, EntityId entityId)
|
||||
{
|
||||
auto *transformManager = reinterpret_cast<filament::TransformManager *>(tTransformManager);
|
||||
const auto &entity = utils::Entity::import(entityId);
|
||||
auto transformInstance = transformManager->getInstance(entity);
|
||||
if (!transformInstance)
|
||||
{
|
||||
Log("Failed to find transform instance");
|
||||
return double4x4();
|
||||
}
|
||||
auto transform = transformManager->getTransformAccurate(transformInstance);
|
||||
return convert_mat4_to_double4x4(transform);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE double4x4 TransformManager_getWorldTransform(TTransformManager *tTransformManager, EntityId entityId)
|
||||
{
|
||||
auto *transformManager = reinterpret_cast<filament::TransformManager *>(tTransformManager);
|
||||
const auto &entity = utils::Entity::import(entityId);
|
||||
auto transformInstance = transformManager->getInstance(entity);
|
||||
if (!transformInstance)
|
||||
{
|
||||
Log("Failed to find transform instance");
|
||||
return double4x4();
|
||||
}
|
||||
auto transform = transformManager->getWorldTransformAccurate(transformInstance);
|
||||
return convert_mat4_to_double4x4(transform);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void TransformManager_setTransform(TTransformManager *tTransformManager, EntityId entityId, double4x4 transform)
|
||||
{
|
||||
auto *transformManager = reinterpret_cast<filament::TransformManager *>(tTransformManager);
|
||||
const auto &entity = utils::Entity::import(entityId);
|
||||
auto transformInstance = transformManager->getInstance(entity);
|
||||
if (!transformInstance)
|
||||
{
|
||||
return;
|
||||
}
|
||||
transformManager->setTransform(transformInstance, convert_double4x4_to_mat4(transform));
|
||||
}
|
||||
|
||||
// EMSCRIPTEN_KEEPALIVE void TransformManager_transformToUnitCube(TTransformManager *tTransformManager, EntityId entityId) {
|
||||
// auto *transformManager = reinterpret_cast<filament::TransformManager*>(tTransformManager);
|
||||
// const auto &entity = utils::Entity::import(entityId);
|
||||
// auto transformInstance = transformManager->getInstance(entity);
|
||||
// if (!transformInstance)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// auto aabb = instance->getBoundingBox();
|
||||
// auto center = aabb.center();
|
||||
// auto halfExtent = aabb.extent();
|
||||
// auto maxExtent = max(halfExtent) * 2;
|
||||
// auto scaleFactor = 2.0f / maxExtent;
|
||||
// auto transform = math::mat4f::scaling(scaleFactor) * math::mat4f::translation(-center);
|
||||
// tm.setTransform(tm.getInstance(instance->getRoot()), transform);
|
||||
// }
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void TransformManager_setParent(TTransformManager *tTransformManager, EntityId childId, EntityId parentId, bool preserveScaling)
|
||||
{
|
||||
auto tm = reinterpret_cast<TransformManager *>(tTransformManager);
|
||||
const auto child = Entity::import(childId);
|
||||
const auto parent = Entity::import(parentId);
|
||||
|
||||
const auto &parentInstance = tm->getInstance(parent);
|
||||
const auto &childInstance = tm->getInstance(child);
|
||||
|
||||
if (!parentInstance.isValid())
|
||||
{
|
||||
Log("Parent instance is not valid");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!childInstance.isValid())
|
||||
{
|
||||
Log("Child instance is not valid");
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
tm->setParent(childInstance, parentInstance);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE EntityId TransformManager_getParent(TTransformManager *tTransformManager, EntityId childId)
|
||||
{
|
||||
auto tm = reinterpret_cast<TransformManager *>(tTransformManager);
|
||||
const auto child = Entity::import(childId);
|
||||
const auto &childInstance = tm->getInstance(child);
|
||||
|
||||
return Entity::smuggle(tm->getParent(childInstance));
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE EntityId TransformManager_getAncestor(TTransformManager *tTransformManager, EntityId childEntityId)
|
||||
{
|
||||
auto tm = reinterpret_cast<TransformManager *>(tTransformManager);
|
||||
|
||||
const auto child = Entity::import(childEntityId);
|
||||
auto transformInstance = tm->getInstance(child);
|
||||
Entity parent;
|
||||
|
||||
while (true)
|
||||
{
|
||||
auto newParent = tm->getParent(transformInstance);
|
||||
if (newParent.isNull())
|
||||
{
|
||||
break;
|
||||
}
|
||||
parent = newParent;
|
||||
transformInstance = tm->getInstance(parent);
|
||||
}
|
||||
|
||||
return Entity::smuggle(parent);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user