Files
filament/libs/gltfio/src/FilamentAsset.cpp
Philip Rideout 82fcb656d9 gltfio: Use BufferObject API, simplify MorphHelper. (#3737)
* gltfio: Use BufferObject API, simplify MorphHelper.

* Repair Android build.
2021-04-05 13:00:39 -07:00

290 lines
8.1 KiB
C++

/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "FFilamentAsset.h"
#include <gltfio/Animator.h>
#include <utils/EntityManager.h>
#include <utils/Log.h>
#include <utils/NameComponentManager.h>
#include "Wireframe.h"
using namespace filament;
using namespace utils;
namespace gltfio {
FFilamentAsset::~FFilamentAsset() {
releaseSourceData();
// The only things we need to free in the instances are their animators.
// The union of all instance entities will be destroyed below.
for (FFilamentInstance* instance : mInstances) {
delete instance->animator;
delete instance;
}
delete mAnimator;
delete mWireframe;
mEngine->destroy(mRoot);
mEntityManager->destroy(mRoot);
for (auto entity : mEntities) {
// Destroy the entity's renderable, light, transform, and camera components.
mEngine->destroy(entity);
// Destroy the name component.
if (mNameManager) {
mNameManager->removeComponent(entity);
}
// Destroy the actual entity.
mEntityManager->destroy(entity);
}
for (auto mi : mMaterialInstances) {
mEngine->destroy(mi);
}
for (auto vb : mVertexBuffers) {
mEngine->destroy(vb);
}
for (auto bo : mBufferObjects) {
mEngine->destroy(bo);
}
for (auto ib : mIndexBuffers) {
mEngine->destroy(ib);
}
for (auto tx : mTextures) {
mEngine->destroy(tx);
}
}
Animator* FFilamentAsset::getAnimator() noexcept {
if (!mAnimator) {
if (!mResourcesLoaded) {
slog.e << "Cannot create animator before resource loading." << io::endl;
return nullptr;
}
if (!mSourceAsset) {
slog.e << "Cannot create animator from frozen asset." << io::endl;
return nullptr;
}
mAnimator = new Animator(this, nullptr);
}
return mAnimator;
}
Entity FFilamentAsset::getWireframe() noexcept {
if (!mWireframe) {
mWireframe = new Wireframe(this);
}
return mWireframe->mEntity;
}
void FFilamentAsset::releaseSourceData() noexcept {
// To ensure that all possible memory is freed, we reassign to new containers rather than
// calling clear(). With many container types (such as robin_map), clearing is a fast
// operation that merely frees the storage for the items.
mMatInstanceCache = {};
mMeshCache = {};
mResourceUris = {};
mNodeMap = {};
mPrimitives = {};
mBufferSlots = {};
mTextureSlots = {};
mSourceAsset.reset();
for (FFilamentInstance* instance : mInstances) {
instance->nodeMap = {};
}
}
const char* FFilamentAsset::getName(utils::Entity entity) const noexcept {
if (mNameManager == nullptr) {
return nullptr;
}
auto nameInstance = mNameManager->getInstance(entity);
return nameInstance ? mNameManager->getName(nameInstance) : nullptr;
}
Entity FFilamentAsset::getFirstEntityByName(const char* name) noexcept {
const auto iter = mNameToEntity.find(name);
if (iter == mNameToEntity.end()) {
return {};
}
return iter->front();
}
size_t FFilamentAsset::getEntitiesByName(const char* name, Entity* entities,
size_t maxCount) const noexcept {
const auto iter = mNameToEntity.find(name);
if (iter == mNameToEntity.end()) {
return 0;
}
const auto& source = *iter;
if (entities == nullptr) {
return source.size();
}
maxCount = std::min(maxCount, source.size());
if (maxCount == 0) {
return 0;
}
size_t count = 0;
for (Entity entity : source) {
entities[count] = entity;
if (++count >= maxCount) {
return count;
}
}
return count;
}
size_t FFilamentAsset::getEntitiesByPrefix(const char* prefix, Entity* entities,
size_t maxCount) const noexcept {
const auto range = mNameToEntity.equal_prefix_range(prefix);
size_t count = 0;
for (auto iter = range.first; iter != range.second; ++iter) {
count += iter->size();
}
if (entities == nullptr) {
return count;
}
maxCount = std::min(maxCount, count);
if (maxCount == 0) {
return 0;
}
count = 0;
for (auto iter = range.first; iter != range.second; ++iter) {
const auto& source = *iter;
for (Entity entity : source) {
entities[count] = entity;
if (++count >= maxCount) {
return count;
}
}
}
return count;
}
size_t FilamentAsset::getEntityCount() const noexcept {
return upcast(this)->getEntityCount();
}
const Entity* FilamentAsset::getEntities() const noexcept {
return upcast(this)->getEntities();
}
const Entity* FilamentAsset::getLightEntities() const noexcept {
return upcast(this)->getLightEntities();
}
size_t FilamentAsset::getLightEntityCount() const noexcept {
return upcast(this)->getLightEntityCount();
}
const utils::Entity* FilamentAsset::getCameraEntities() const noexcept {
return upcast(this)->getCameraEntities();
}
size_t FilamentAsset::getCameraEntityCount() const noexcept {
return upcast(this)->getCameraEntityCount();
}
Entity FilamentAsset::getRoot() const noexcept {
return upcast(this)->getRoot();
}
Entity FilamentAsset::popRenderable() noexcept {
Entity result[1];
const bool empty = !popRenderables(result, 1);
return empty ? Entity() : result[0];
}
size_t FilamentAsset::popRenderables(Entity* result, size_t count) noexcept {
return upcast(this)->popRenderables(result, count);
}
size_t FilamentAsset::getMaterialInstanceCount() const noexcept {
return upcast(this)->getMaterialInstanceCount();
}
const MaterialInstance* const* FilamentAsset::getMaterialInstances() const noexcept {
return upcast(this)->getMaterialInstances();
}
MaterialInstance* const* FilamentAsset::getMaterialInstances() noexcept {
return upcast(this)->getMaterialInstances();
}
size_t FilamentAsset::getResourceUriCount() const noexcept {
return upcast(this)->getResourceUriCount();
}
const char* const* FilamentAsset::getResourceUris() const noexcept {
return upcast(this)->getResourceUris();
}
filament::Aabb FilamentAsset::getBoundingBox() const noexcept {
return upcast(this)->getBoundingBox();
}
const char* FilamentAsset::getName(Entity entity) const noexcept {
return upcast(this)->getName(entity);
}
Entity FilamentAsset::getFirstEntityByName(const char* name) noexcept {
return upcast(this)->getFirstEntityByName(name);
}
size_t FilamentAsset::getEntitiesByName(const char* name, Entity* entities,
size_t maxCount) const noexcept {
return upcast(this)->getEntitiesByName(name, entities, maxCount);
}
size_t FilamentAsset::getEntitiesByPrefix(const char* prefix, Entity* entities,
size_t maxCount) const noexcept {
return upcast(this)->getEntitiesByPrefix(prefix, entities, maxCount);
}
Animator* FilamentAsset::getAnimator() noexcept {
return upcast(this)->getAnimator();
}
Entity FilamentAsset::getWireframe() noexcept {
return upcast(this)->getWireframe();
}
Engine* FilamentAsset::getEngine() const noexcept {
return upcast(this)->getEngine();
}
void FilamentAsset::releaseSourceData() noexcept {
return upcast(this)->releaseSourceData();
}
const void* FilamentAsset::getSourceAsset() noexcept {
return upcast(this)->getSourceAsset();
}
FilamentInstance** FilamentAsset::getAssetInstances() noexcept {
return upcast(this)->getAssetInstances();
}
size_t FilamentAsset::getAssetInstanceCount() const noexcept {
return upcast(this)->getAssetInstanceCount();
}
} // namespace gltfio