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:
Nick Fisher
2024-11-21 15:04:10 +08:00
parent 9ada6aae64
commit ed444b0615
195 changed files with 18061 additions and 12628 deletions

View File

@@ -0,0 +1,61 @@
#include "scene/GltfSceneAsset.hpp"
#include "scene/GltfSceneAssetInstance.hpp"
#include "gltfio/FilamentInstance.h"
#include "Log.hpp"
namespace thermion
{
GltfSceneAsset::~GltfSceneAsset()
{
_instances.clear();
_asset->releaseSourceData();
_assetLoader->destroyAsset(_asset);
}
SceneAsset *GltfSceneAsset::createInstance(MaterialInstance **materialInstances, size_t materialInstanceCount)
{
auto instanceNumber = _instances.size();
if (instanceNumber > _asset->getAssetInstanceCount() - 1)
{
Log("No instances available for reuse. When loading the asset, you must pre-allocate the number of instances you wish to make available for use. Try increasing this number.");
return std::nullptr_t();
}
Log("Creating instance %d", instanceNumber);
auto instance = _asset->getAssetInstances()[instanceNumber];
instance->recomputeBoundingBoxes();
instance->getAnimator()->updateBoneMatrices();
auto& rm = _engine->getRenderableManager();
if(materialInstanceCount > 0) {
for(int i = 0; i < instance->getEntityCount(); i++) {
auto renderableInstance = rm.getInstance(instance->getEntities()[i]);
if(!renderableInstance.isValid()) {
Log("Instance is not renderable");
} else {
for(int i = 0; i < materialInstanceCount; i++) {
rm.setMaterialInstanceAt(renderableInstance, i, materialInstances[i]);
}
}
}
}
std::unique_ptr<GltfSceneAssetInstance> sceneAssetInstance = std::make_unique<GltfSceneAssetInstance>(
instance,
_engine,
materialInstances,
materialInstanceCount
);
auto *raw = sceneAssetInstance.get();
_instances.push_back(std::move(sceneAssetInstance));
return raw;
}
}