feat: add flag for keepData for gltf instancing, add highlightScene, add stencilHighlight method

This commit is contained in:
Nick Fisher
2024-09-06 12:36:16 +08:00
parent 1b50ca2b57
commit 0a4e3501dc
20 changed files with 1967 additions and 93 deletions

View File

@@ -22,7 +22,7 @@
* limitations under the License.
*/
#include <filament/Camera.h>
#include <filament/SwapChain.h>
#include <backend/DriverEnums.h>
#include <backend/platforms/OpenGLPlatform.h>
#ifdef __EMSCRIPTEN__
@@ -158,6 +158,7 @@ namespace thermion_filament
setFrameInterval(_frameInterval);
_scene = _engine->createScene();
_highlightScene = _engine->createScene();
utils::Entity camera = EntityManager::get().create();
@@ -195,8 +196,6 @@ namespace thermion_filament
const float shutterSpeed = _mainCamera->getShutterSpeed();
const float sens = _mainCamera->getSensitivity();
Log("Camera aperture %f shutter %f sensitivity %f", aperture, shutterSpeed, sens);
EntityManager &em = EntityManager::get();
_sceneManager = new SceneManager(
@@ -204,6 +203,7 @@ namespace thermion_filament
_resourceLoaderWrapper,
_engine,
_scene,
_highlightScene,
uberArchivePath);
}
@@ -780,7 +780,7 @@ namespace thermion_filament
else
{
Log("Created headless swapchain.");
_swapChain = _engine->createSwapChain(width, height, filament::backend::SWAP_CHAIN_CONFIG_TRANSPARENT | filament::backend::SWAP_CHAIN_CONFIG_READABLE);
_swapChain = _engine->createSwapChain(width, height, filament::backend::SWAP_CHAIN_CONFIG_TRANSPARENT | filament::backend::SWAP_CHAIN_CONFIG_READABLE | filament::SwapChain::CONFIG_HAS_STENCIL_BUFFER);
}
#endif
}
@@ -800,7 +800,7 @@ namespace thermion_filament
.width(width)
.height(height)
.levels(1)
.usage(filament::Texture::Usage::DEPTH_ATTACHMENT)
.usage(filament::Texture::Usage::DEPTH_ATTACHMENT | filament::Texture::Usage::SAMPLEABLE)
.format(filament::Texture::InternalFormat::DEPTH32F)
.build(*_engine);
_rt = filament::RenderTarget::Builder()
@@ -1180,24 +1180,12 @@ namespace thermion_filament
void *data)
{
if (!_view)
{
Log("No view");
return;
}
else if (!_swapChain)
{
Log("No swapchain");
return;
}
auto now = std::chrono::high_resolution_clock::now();
auto secsSinceLastFpsCheck = float(std::chrono::duration_cast<std::chrono::seconds>(now - _fpsCounterStartTime).count());
if (secsSinceLastFpsCheck >= 1)
{
auto fps = _frameCount / secsSinceLastFpsCheck;
Log("%ffps (%d skipped)", fps, _skippedFrames);
_frameCount = 0;
_skippedFrames = 0;
_fpsCounterStartTime = now;
@@ -1231,6 +1219,12 @@ namespace thermion_filament
_renderer->render(_view);
_view->setScene(_highlightScene);
_renderer->render(_view);
_view->setScene(_scene);
_frameCount++;
if (_recording)
@@ -1295,6 +1289,12 @@ namespace thermion_filament
_renderer->render(_view);
_view->setScene(_highlightScene);
_renderer->render(_view);
_view->setScene(_scene);
if (_rt)
{
_renderer->readPixels(_rt, 0, 0, vp.width, vp.height, std::move(pbd));

View File

@@ -24,6 +24,9 @@
#include <imageio/ImageDecoder.h>
#include "material/FileMaterialProvider.hpp"
#include "material/UnlitMaterialProvider.hpp"
#include "material/unlit.h"
#include "StreamBufferAdapter.hpp"
#include "Log.hpp"
#include "SceneManager.hpp"
@@ -49,11 +52,13 @@ namespace thermion_filament
const ResourceLoaderWrapperImpl *const resourceLoaderWrapper,
Engine *engine,
Scene *scene,
Scene *highlightScene,
const char *uberArchivePath)
: _view(view),
_resourceLoaderWrapper(resourceLoaderWrapper),
_engine(engine),
_scene(scene)
_scene(scene),
_highlightScene(highlightScene)
{
_stbDecoder = createStbProvider(_engine);
@@ -77,6 +82,8 @@ namespace thermion_filament
_engine, UBERARCHIVE_DEFAULT_DATA, UBERARCHIVE_DEFAULT_SIZE);
}
_unlitMaterialProvider = new UnlitMaterialProvider(_engine, UNLIT_PACKAGE, UNLIT_UNLIT_SIZE);
utils::EntityManager &em = utils::EntityManager::get();
_ncm = new NameComponentManager(em);
@@ -152,7 +159,8 @@ namespace thermion_filament
}
EntityId SceneManager::loadGltf(const char *uri,
const char *relativeResourcePath)
const char *relativeResourcePath,
bool keepData)
{
ResourceBuffer rbuf = _resourceLoaderWrapper->load(uri);
@@ -172,7 +180,6 @@ namespace thermion_filament
for (size_t i = 0; i < resourceUriCount; i++)
{
std::string uri = std::string(relativeResourcePath) + std::string("/") + std::string(resourceUris[i]);
Log("Loading resource URI from relative path %s", resourceUris[i], uri.c_str());
ResourceBuffer buf = _resourceLoaderWrapper->load(uri.c_str());
resourceBuffers.push_back(buf);
@@ -215,8 +222,10 @@ namespace thermion_filament
FilamentInstance *inst = asset->getInstance();
inst->getAnimator()->updateBoneMatrices();
inst->recomputeBoundingBoxes();
asset->releaseSourceData();
if(!keepData) {
asset->releaseSourceData();
}
EntityId eid = Entity::smuggle(asset->getRoot());
@@ -233,11 +242,9 @@ namespace thermion_filament
return eid;
}
EntityId SceneManager::loadGlbFromBuffer(const uint8_t *data, size_t length, int numInstances)
EntityId SceneManager::loadGlbFromBuffer(const uint8_t *data, size_t length, int numInstances, bool keepData)
{
Log("Loading GLB from buffer of length %d", length);
FilamentAsset *asset = nullptr;
if (numInstances > 1)
{
@@ -290,7 +297,9 @@ namespace thermion_filament
_instances.emplace(instanceEntityId, inst);
}
asset->releaseSourceData();
if(!keepData) {
asset->releaseSourceData();
}
EntityId eid = Entity::smuggle(asset->getRoot());
_assets.emplace(eid, asset);
@@ -352,18 +361,26 @@ namespace thermion_filament
if (pos == _assets.end())
{
Log("Couldn't find asset under specified entity id.");
return false;
return 0;
}
const auto asset = pos->second;
auto instance = _assetLoader->createInstance(asset);
return Entity::smuggle(instance->getRoot());
if(!instance) {
Log("Failed to create instance");
return 0;
}
auto root = instance->getRoot();
_scene->addEntities(instance->getEntities(), instance->getEntityCount());
return Entity::smuggle(root);
}
EntityId SceneManager::loadGlb(const char *uri, int numInstances)
EntityId SceneManager::loadGlb(const char *uri, int numInstances, bool keepData)
{
ResourceBuffer rbuf = _resourceLoaderWrapper->load(uri);
auto entity = loadGlbFromBuffer((const uint8_t *)rbuf.data, rbuf.size, numInstances);
auto entity = loadGlbFromBuffer((const uint8_t *)rbuf.data, rbuf.size, numInstances, keepData);
_resourceLoaderWrapper->free(rbuf);
return entity;
}
@@ -2272,8 +2289,11 @@ void SceneManager::queueRelativePositionUpdateWorldAxis(EntityId entity, float v
void SceneManager::setLayerEnabled(int layer, bool enabled)
{
Log("Setting layer %d to %d", layer, enabled);
_view->setLayerEnabled(layer, enabled);
}
}
} // namespace thermion_filament

View File

@@ -166,14 +166,14 @@ extern "C"
((FilamentViewer *)viewer)->clearLights();
}
EMSCRIPTEN_KEEPALIVE EntityId load_glb(void *sceneManager, const char *assetPath, int numInstances)
EMSCRIPTEN_KEEPALIVE EntityId load_glb(void *sceneManager, const char *assetPath, int numInstances, bool keepData)
{
return ((SceneManager *)sceneManager)->loadGlb(assetPath, numInstances);
return ((SceneManager *)sceneManager)->loadGlb(assetPath, numInstances, keepData);
}
EMSCRIPTEN_KEEPALIVE EntityId load_glb_from_buffer(void *sceneManager, const void *const data, size_t length)
EMSCRIPTEN_KEEPALIVE EntityId load_glb_from_buffer(void *sceneManager, const void *const data, size_t length, bool keepData)
{
return ((SceneManager *)sceneManager)->loadGlbFromBuffer((const uint8_t *)data, length);
return ((SceneManager *)sceneManager)->loadGlbFromBuffer((const uint8_t *)data, length, keepData);
}
EMSCRIPTEN_KEEPALIVE EntityId create_instance(void *sceneManager, EntityId entityId)
@@ -191,9 +191,9 @@ extern "C"
return ((SceneManager *)sceneManager)->getInstances(entityId, out);
}
EMSCRIPTEN_KEEPALIVE EntityId load_gltf(void *sceneManager, const char *assetPath, const char *relativePath)
EMSCRIPTEN_KEEPALIVE EntityId load_gltf(void *sceneManager, const char *assetPath, const char *relativePath, bool keepData)
{
return ((SceneManager *)sceneManager)->loadGltf(assetPath, relativePath);
return ((SceneManager *)sceneManager)->loadGltf(assetPath, relativePath, keepData);
}
EMSCRIPTEN_KEEPALIVE void set_main_camera(const void *const viewer)
@@ -892,7 +892,10 @@ extern "C"
EMSCRIPTEN_KEEPALIVE void set_gizmo_visibility(void *const sceneManager, bool visible) {
((SceneManager*)sceneManager)->gizmo->setVisibility(visible);
}
EMSCRIPTEN_KEEPALIVE void set_stencil_highlight(void *const sceneManager, EntityId entityId) {
((SceneManager*)sceneManager)->setStencilHighlight(entityId);
}

View File

@@ -392,11 +392,12 @@ extern "C"
EMSCRIPTEN_KEEPALIVE void load_gltf_ffi(void *const sceneManager,
const char *path,
const char *relativeResourcePath,
bool keepData,
void (*callback)(EntityId))
{
std::packaged_task<EntityId()> lambda([=]() mutable
{
auto entity = load_gltf(sceneManager, path, relativeResourcePath);
auto entity = load_gltf(sceneManager, path, relativeResourcePath, keepData);
#ifdef __EMSCRIPTEN__
MAIN_THREAD_EM_ASM({
moduleArg.dartFilamentResolveCallback($0, $1);
@@ -409,12 +410,15 @@ extern "C"
}
EMSCRIPTEN_KEEPALIVE void load_glb_ffi(void *const sceneManager,
const char *path, int numInstances, void (*callback)(EntityId))
const char *path,
int numInstances,
bool keepData,
void (*callback)(EntityId))
{
std::packaged_task<EntityId()> lambda(
[=]() mutable
{
auto entity = load_glb(sceneManager, path, numInstances);
auto entity = load_glb(sceneManager, path, numInstances, keepData);
#ifdef __EMSCRIPTEN__
MAIN_THREAD_EM_ASM({
moduleArg.dartFilamentResolveCallback($0, $1);
@@ -428,12 +432,16 @@ extern "C"
}
EMSCRIPTEN_KEEPALIVE void load_glb_from_buffer_ffi(void *const sceneManager,
const void *const data, size_t length, int numInstances, void (*callback)(EntityId))
const void *const data,
size_t length,
int numInstances,
bool keepData,
void (*callback)(EntityId))
{
std::packaged_task<EntityId()> lambda(
[=]() mutable
{
auto entity = load_glb_from_buffer(sceneManager, data, length);
auto entity = load_glb_from_buffer(sceneManager, data, length, keepData);
callback(entity);
return entity;
});