fix: allow destroying instances independently of owner

This commit is contained in:
Nick Fisher
2025-01-02 16:46:44 +08:00
parent 8e0ba8ac4e
commit 3e181b6aff
13 changed files with 141 additions and 91 deletions

View File

@@ -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