fix: allow destroying instances independently of owner
This commit is contained in:
@@ -19,16 +19,15 @@ namespace thermion
|
||||
using namespace filament;
|
||||
|
||||
GeometrySceneAsset::GeometrySceneAsset(
|
||||
bool isInstance,
|
||||
Engine *engine,
|
||||
VertexBuffer *vertexBuffer,
|
||||
IndexBuffer *indexBuffer,
|
||||
MaterialInstance **materialInstances,
|
||||
size_t materialInstanceCount,
|
||||
RenderableManager::PrimitiveType primitiveType,
|
||||
Box boundingBox)
|
||||
: _isInstance(isInstance),
|
||||
_engine(engine), _vertexBuffer(vertexBuffer), _indexBuffer(indexBuffer), _materialInstances(materialInstances), _materialInstanceCount(materialInstanceCount), _primitiveType(primitiveType), _boundingBox(boundingBox)
|
||||
Box boundingBox,
|
||||
GeometrySceneAsset *instanceOwner)
|
||||
: _engine(engine), _vertexBuffer(vertexBuffer), _indexBuffer(indexBuffer), _materialInstances(materialInstances), _materialInstanceCount(materialInstanceCount), _primitiveType(primitiveType), _boundingBox(boundingBox), _instanceOwner(instanceOwner)
|
||||
{
|
||||
_entity = utils::EntityManager::get().create();
|
||||
|
||||
@@ -49,75 +48,40 @@ namespace thermion
|
||||
{
|
||||
if (_engine)
|
||||
{
|
||||
if (_vertexBuffer && !_isInstance)
|
||||
if (_vertexBuffer && !isInstance())
|
||||
_engine->destroy(_vertexBuffer);
|
||||
if (_indexBuffer && !_isInstance)
|
||||
if (_indexBuffer && !isInstance())
|
||||
_engine->destroy(_indexBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
SceneAsset *GeometrySceneAsset::createInstance(MaterialInstance **materialInstances, size_t materialInstanceCount)
|
||||
{
|
||||
if (_isInstance)
|
||||
if (isInstance())
|
||||
{
|
||||
Log("Cannot create an instance from another instance. Ensure you are calling createInstance with the original asset.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<GeometrySceneAsset> instance = std::make_unique<GeometrySceneAsset>(
|
||||
true,
|
||||
_engine,
|
||||
_vertexBuffer,
|
||||
_indexBuffer,
|
||||
materialInstances,
|
||||
materialInstanceCount,
|
||||
_primitiveType,
|
||||
_boundingBox);
|
||||
_boundingBox,
|
||||
this);
|
||||
auto *raw = instance.get();
|
||||
_instances.push_back(std::move(instance));
|
||||
return raw;
|
||||
}
|
||||
|
||||
// std::unique_ptr<GeometrySceneAsset> GeometrySceneAsset::create(
|
||||
// float *vertices, uint32_t numVertices,
|
||||
// float *normals, uint32_t numNormals,
|
||||
// float *uvs, uint32_t numUvs,
|
||||
// uint16_t *indices, uint32_t numIndices,
|
||||
// MaterialInstance **materialInstances,
|
||||
// size_t materialInstanceCount,
|
||||
// RenderableManager::PrimitiveType primitiveType,
|
||||
// Engine *engine)
|
||||
// {
|
||||
|
||||
// // Setup texture if needed
|
||||
// if (asset && uvs && numUvs > 0 &&
|
||||
// asset->getMaterialInstance() &&
|
||||
// asset->getMaterialInstance()->getMaterial()->hasParameter("baseColorMap"))
|
||||
// {
|
||||
// static constexpr uint32_t textureSize = 1;
|
||||
// static constexpr uint32_t white = 0x00ffffff;
|
||||
|
||||
// auto texture = Texture::Builder()
|
||||
// .width(textureSize)
|
||||
// .height(textureSize)
|
||||
// .levels(1)
|
||||
// .format(Texture::InternalFormat::RGBA8)
|
||||
// .build(*engine);
|
||||
|
||||
// filament::backend::PixelBufferDescriptor pbd(
|
||||
// &white, 4, Texture::Format::RGBA, Texture::Type::UBYTE);
|
||||
// texture->setImage(*engine, 0, std::move(pbd));
|
||||
|
||||
// TextureSampler sampler(
|
||||
// TextureSampler::MinFilter::NEAREST,
|
||||
// TextureSampler::MagFilter::NEAREST);
|
||||
// sampler.setWrapModeS(TextureSampler::WrapMode::REPEAT);
|
||||
// sampler.setWrapModeT(TextureSampler::WrapMode::REPEAT);
|
||||
|
||||
// asset->getMaterialInstance()->setParameter("baseColorMap", texture, sampler);
|
||||
// }
|
||||
|
||||
// return asset;
|
||||
// }
|
||||
void GeometrySceneAsset::destroyInstance(SceneAsset *asset)
|
||||
{
|
||||
auto it = std::remove_if(_instances.begin(), _instances.end(), [=](auto &sceneAsset)
|
||||
{ return sceneAsset.get() == asset; });
|
||||
_instances.erase(it, _instances.end());
|
||||
}
|
||||
|
||||
} // namespace thermion
|
||||
@@ -107,7 +107,6 @@ namespace thermion
|
||||
boundingBox.getMax().x, boundingBox.getMax().y, boundingBox.getMax().z);
|
||||
|
||||
auto asset = std::make_unique<GeometrySceneAsset>(
|
||||
false,
|
||||
mEngine,
|
||||
vertexBuffer,
|
||||
indexBuffer,
|
||||
|
||||
@@ -49,6 +49,7 @@ namespace thermion
|
||||
}
|
||||
|
||||
std::unique_ptr<GltfSceneAssetInstance> sceneAssetInstance = std::make_unique<GltfSceneAssetInstance>(
|
||||
this,
|
||||
instance,
|
||||
_engine,
|
||||
_ncm,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
#include "scene/GltfSceneAssetInstance.hpp"
|
||||
#include "gltfio/FilamentInstance.h"
|
||||
#include "Log.hpp"
|
||||
#include "scene/GltfSceneAsset.hpp"
|
||||
|
||||
|
||||
namespace thermion
|
||||
{
|
||||
|
||||
@@ -10,5 +10,9 @@ namespace thermion
|
||||
|
||||
}
|
||||
|
||||
SceneAsset *GltfSceneAssetInstance::getInstanceOwner() {
|
||||
return static_cast<SceneAsset *>(_instanceOwner);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -157,12 +157,13 @@ namespace thermion
|
||||
{
|
||||
if (!_grid)
|
||||
{
|
||||
if(!material) {
|
||||
if (!material)
|
||||
{
|
||||
material = Material::Builder()
|
||||
.package(GRID_PACKAGE, GRID_GRID_SIZE)
|
||||
.build(*_engine);
|
||||
.package(GRID_PACKAGE, GRID_GRID_SIZE)
|
||||
.build(*_engine);
|
||||
}
|
||||
|
||||
|
||||
_grid = std::make_unique<GridOverlay>(*_engine, material);
|
||||
}
|
||||
return _grid.get();
|
||||
@@ -344,7 +345,7 @@ namespace thermion
|
||||
|
||||
_sceneAssets.push_back(std::move(sceneAsset));
|
||||
|
||||
Log("Finished loading glTF from %s", uri);
|
||||
Log("Loaded glTF asset from uri: %s", uri);
|
||||
|
||||
return raw;
|
||||
}
|
||||
@@ -492,22 +493,25 @@ namespace thermion
|
||||
|
||||
std::lock_guard lock(_mutex);
|
||||
|
||||
auto it = std::remove_if(_sceneAssets.begin(), _sceneAssets.end(), [=](auto &sceneAsset)
|
||||
{ return sceneAsset.get() == asset; });
|
||||
if (it != _sceneAssets.end())
|
||||
auto entity = asset->getEntity();
|
||||
_collisionComponentManager->removeComponent(entity);
|
||||
_animationManager->removeAnimationComponent(utils::Entity::smuggle(entity));
|
||||
for (int i = 0; i < asset->getChildEntityCount(); i++)
|
||||
{
|
||||
auto entity = (*it)->getEntity();
|
||||
_collisionComponentManager->removeComponent(entity);
|
||||
_animationManager->removeAnimationComponent(utils::Entity::smuggle(entity));
|
||||
for (int i = 0; i < (*it)->getChildEntityCount(); i++)
|
||||
{
|
||||
auto childEntity = (*it)->getChildEntities()[i];
|
||||
_collisionComponentManager->removeComponent(childEntity);
|
||||
_animationManager->removeAnimationComponent(utils::Entity::smuggle(childEntity));
|
||||
}
|
||||
(*it)->removeAllEntities(_scene);
|
||||
auto childEntity = asset->getChildEntities()[i];
|
||||
_collisionComponentManager->removeComponent(childEntity);
|
||||
_animationManager->removeAnimationComponent(utils::Entity::smuggle(childEntity));
|
||||
}
|
||||
asset->removeAllEntities(_scene);
|
||||
if (asset->isInstance())
|
||||
{
|
||||
asset->destroyInstance(asset);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto it = std::remove_if(_sceneAssets.begin(), _sceneAssets.end(), [=](auto &sceneAsset)
|
||||
{ return sceneAsset.get() == asset; });
|
||||
_sceneAssets.erase(it, _sceneAssets.end());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user