refactor!: refactor to support multiple Views/Render Targets

This commit is contained in:
Nick Fisher
2024-09-27 23:16:01 +08:00
parent ef5b12af4f
commit a5ca6132f0
25 changed files with 1137 additions and 1304 deletions

View File

@@ -164,31 +164,7 @@ namespace thermion_filament
_mainCamera = _engine->createCamera(camera);
_view = _engine->createView();
_view->setBlendMode(filament::View::BlendMode::TRANSLUCENT);
_view->setStencilBufferEnabled(true);
setToneMapping(ToneMapping::ACES);
// there's a glitch on certain iGPUs where nothing will render when postprocessing is enabled and bloom is disabled
// set bloom to a small value here
setBloom(0.01);
_view->setAmbientOcclusionOptions({.enabled = false});
_view->setDynamicResolutionOptions({.enabled = false});
#if defined(_WIN32)
_view->setStereoscopicOptions({.enabled = true});
#endif
_view->setDithering(filament::Dithering::NONE);
setAntiAliasing(false, false, false);
_view->setShadowingEnabled(false);
_view->setScreenSpaceRefractionEnabled(false);
setPostProcessing(false);
_view->setScene(_scene);
_view->setCamera(_mainCamera);
createView();
const float aperture = _mainCamera->getAperture();
const float shutterSpeed = _mainCamera->getShutterSpeed();
@@ -197,7 +173,6 @@ namespace thermion_filament
EntityManager &em = EntityManager::get();
_sceneManager = new SceneManager(
_view,
_resourceLoaderWrapper,
_engine,
_scene,
@@ -205,80 +180,6 @@ namespace thermion_filament
_mainCamera);
}
void FilamentViewer::setAntiAliasing(bool msaa, bool fxaa, bool taa)
{
View::MultiSampleAntiAliasingOptions multiSampleAntiAliasingOptions;
multiSampleAntiAliasingOptions.enabled = msaa;
_view->setMultiSampleAntiAliasingOptions(multiSampleAntiAliasingOptions);
TemporalAntiAliasingOptions taaOpts;
taaOpts.enabled = taa;
_view->setTemporalAntiAliasingOptions(taaOpts);
_view->setAntiAliasing(fxaa ? AntiAliasing::FXAA : AntiAliasing::NONE);
}
void FilamentViewer::setPostProcessing(bool enabled)
{
_view->setPostProcessingEnabled(enabled);
}
void FilamentViewer::setShadowsEnabled(bool enabled)
{
_view->setShadowingEnabled(enabled);
}
void FilamentViewer::setShadowType(ShadowType shadowType)
{
_view->setShadowType(shadowType);
}
void FilamentViewer::setSoftShadowOptions(float penumbraScale, float penumbraRatioScale)
{
SoftShadowOptions opts;
opts.penumbraRatioScale = penumbraRatioScale;
opts.penumbraScale = penumbraScale;
_view->setSoftShadowOptions(opts);
}
void FilamentViewer::setBloom(float strength)
{
#ifndef __EMSCRIPTEN__
decltype(_view->getBloomOptions()) opts;
opts.enabled = true;
opts.strength = strength;
_view->setBloomOptions(opts);
#endif
}
void FilamentViewer::setToneMapping(ToneMapping toneMapping)
{
ToneMapper *tm;
switch (toneMapping)
{
case ToneMapping::ACES:
Log("Setting tone mapping to ACES");
tm = new ACESToneMapper();
break;
case ToneMapping::LINEAR:
Log("Setting tone mapping to Linear");
tm = new LinearToneMapper();
break;
case ToneMapping::FILMIC:
Log("Setting tone mapping to Filmic");
tm = new FilmicToneMapper();
break;
default:
Log("ERROR: Unsupported tone mapping");
return;
}
auto newColorGrading = ColorGrading::Builder().toneMapper(tm).build(*_engine);
_view->setColorGrading(newColorGrading);
_engine->destroy(colorGrading);
delete tm;
}
void FilamentViewer::setFrameInterval(float frameInterval)
{
_frameInterval = frameInterval;
@@ -307,7 +208,7 @@ namespace thermion_filament
bool shadows)
{
auto light = EntityManager::get().create();
auto result = LightManager::Builder(t)
.color(Color::cct(colour))
.intensity(intensity)
@@ -333,36 +234,38 @@ namespace thermion_filament
return Entity::smuggle(light);
}
void FilamentViewer::setLightPosition(EntityId entityId, float x, float y, float z) {
void FilamentViewer::setLightPosition(EntityId entityId, float x, float y, float z)
{
auto light = Entity::import(entityId);
if(light.isNull()) {
if (light.isNull())
{
Log("Light not found for entity %d", entityId);
return;
}
auto& lm = _engine->getLightManager();
auto &lm = _engine->getLightManager();
auto instance = lm.getInstance(light);
lm.setPosition(instance, filament::math::float3 { x, y, z });
lm.setPosition(instance, filament::math::float3{x, y, z});
}
void FilamentViewer::setLightDirection(EntityId entityId, float x, float y, float z) {
void FilamentViewer::setLightDirection(EntityId entityId, float x, float y, float z)
{
auto light = Entity::import(entityId);
if(light.isNull()) {
if (light.isNull())
{
Log("Light not found for entity %d", entityId);
return;
}
auto& lm = _engine->getLightManager();
auto &lm = _engine->getLightManager();
auto instance = lm.getInstance(light);
lm.setDirection(instance, filament::math::float3 { x, y, z });
lm.setDirection(instance, filament::math::float3{x, y, z});
}
void FilamentViewer::removeLight(EntityId entityId)
@@ -608,7 +511,7 @@ namespace thermion_filament
}
}
void FilamentViewer::setBackgroundImage(const char *resourcePath, bool fillHeight)
void FilamentViewer::setBackgroundImage(const char *resourcePath, bool fillHeight, uint32_t width, uint32_t height)
{
std::lock_guard lock(_imageMutex);
@@ -624,9 +527,7 @@ namespace thermion_filament
// This currently just anchors the image at the bottom left of the viewport at its original size
// TODO - implement stretch/etc
const Viewport &vp = _view->getViewport();
float xScale = float(vp.width) / float(_imageWidth);
float xScale = float(width) / float(_imageWidth);
float yScale;
if (fillHeight)
@@ -635,7 +536,7 @@ namespace thermion_filament
}
else
{
yScale = float(vp.height) / float(_imageHeight);
yScale = float(height) / float(_imageHeight);
}
_imageScale = mat4f{xScale, 0.0f, 0.0f, 0.0f, 0.0f, yScale, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
@@ -643,7 +544,6 @@ namespace thermion_filament
_imageMaterial->setDefaultParameter("transform", _imageScale);
_imageMaterial->setDefaultParameter("image", _imageTexture, _imageSampler);
_imageMaterial->setDefaultParameter("showImage", 1);
}
///
@@ -652,7 +552,7 @@ namespace thermion_filament
/// are positioned at a max/min of -1/1 respectively
/// (i.e. you cannot set a position where the left/top or right/bottom sides would be "inside" the screen coordinate space).
///
void FilamentViewer::setBackgroundImagePosition(float x, float y, bool clamp = false)
void FilamentViewer::setBackgroundImagePosition(float x, float y, bool clamp = false, uint32_t width = 0, uint32_t height = 0)
{
std::lock_guard lock(_imageMutex);
@@ -678,8 +578,8 @@ namespace thermion_filament
{
Log("Clamping background image translation");
// first, clamp x/y
auto xScale = float(_imageWidth) / _view->getViewport().width;
auto yScale = float(_imageHeight) / _view->getViewport().height;
auto xScale = float(_imageWidth) / width;
auto yScale = float(_imageHeight) / height;
float xMin = 0;
float xMax = 0;
@@ -720,31 +620,30 @@ namespace thermion_filament
// i.e. translating the image right by 0.5 units means translating the UV coordinates left by 0.5 units.
x = -x;
y = -y;
Log("x %f y %f", x, y);
Log("imageScale %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f ", _imageScale[0][0], _imageScale[0][1], _imageScale[0][2], _imageScale[0][3],
_imageScale[1][0], _imageScale[1][1], _imageScale[1][2], _imageScale[1][3],
_imageScale[2][0], _imageScale[2][1], _imageScale[2][2], _imageScale[2][3],
_imageScale[3][0], _imageScale[3][1], _imageScale[3][2], _imageScale[3][3]);
auto transform = math::mat4f::translation(filament::math::float3(x, y, 0.0f)) * _imageScale;
Log("transform %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f ", transform[0][0], transform[0][1], transform[0][2], transform[0][3],
transform[1][0], transform[1][1], transform[1][2], transform[1][3],
transform[2][0], transform[2][1], transform[2][2], transform[2][3],
transform[3][0], transform[3][1], transform[3][2], transform[3][3]);
_imageMaterial->setDefaultParameter("transform", transform);
}
FilamentViewer::~FilamentViewer()
{
clearLights();
for(auto swapChain : _swapChains) {
for (auto view : _views)
{
_engine->destroy(view);
}
_views.clear();
for (auto swapChain : _swapChains)
{
_engine->destroy(swapChain);
}
_swapChains.clear();
if (!_imageEntity.isNull())
{
_engine->destroy(_imageEntity);
@@ -756,7 +655,6 @@ namespace thermion_filament
delete _sceneManager;
_engine->destroyCameraComponent(_mainCamera->getEntity());
_mainCamera = nullptr;
_engine->destroy(_view);
_engine->destroy(_scene);
_engine->destroy(_renderer);
Engine::destroy(&_engine);
@@ -765,10 +663,10 @@ namespace thermion_filament
Renderer *FilamentViewer::getRenderer() { return _renderer; }
SwapChain* FilamentViewer::createSwapChain(const void *window, uint32_t width, uint32_t height)
SwapChain *FilamentViewer::createSwapChain(const void *window, uint32_t width, uint32_t height)
{
std::lock_guard lock(_renderMutex);
SwapChain* swapChain;
SwapChain *swapChain;
#if TARGET_OS_IPHONE
swapChain = _engine->createSwapChain((void *)window, filament::backend::SWAP_CHAIN_CONFIG_TRANSPARENT | filament::backend::SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER);
#else
@@ -787,58 +685,58 @@ namespace thermion_filament
return swapChain;
}
RenderTarget* FilamentViewer::createRenderTarget(intptr_t texture, uint32_t width, uint32_t height)
RenderTarget *FilamentViewer::createRenderTarget(intptr_t texture, uint32_t width, uint32_t height)
{
// Create filament textures and render targets (note the color buffer has the import call)
auto rtColor = filament::Texture::Builder()
.width(width)
.height(height)
.levels(1)
.usage(filament::Texture::Usage::COLOR_ATTACHMENT | filament::Texture::Usage::SAMPLEABLE)
.format(filament::Texture::InternalFormat::RGBA8)
.import(texture)
.build(*_engine);
.width(width)
.height(height)
.levels(1)
.usage(filament::Texture::Usage::COLOR_ATTACHMENT | filament::Texture::Usage::SAMPLEABLE)
.format(filament::Texture::InternalFormat::RGBA8)
.import(texture)
.build(*_engine);
auto rtDepth = filament::Texture::Builder()
.width(width)
.height(height)
.levels(1)
.usage(filament::Texture::Usage::DEPTH_ATTACHMENT | filament::Texture::Usage::SAMPLEABLE)
.format(filament::Texture::InternalFormat::DEPTH32F)
.build(*_engine);
.width(width)
.height(height)
.levels(1)
.usage(filament::Texture::Usage::DEPTH_ATTACHMENT | filament::Texture::Usage::SAMPLEABLE)
.format(filament::Texture::InternalFormat::DEPTH32F)
.build(*_engine);
auto rt = filament::RenderTarget::Builder()
.texture(RenderTarget::AttachmentPoint::COLOR, rtColor)
.texture(RenderTarget::AttachmentPoint::DEPTH, rtDepth)
.build(*_engine);
return rt;
.texture(RenderTarget::AttachmentPoint::COLOR, rtColor)
.texture(RenderTarget::AttachmentPoint::DEPTH, rtDepth)
.build(*_engine);
return rt;
}
void FilamentViewer::destroyRenderTarget(RenderTarget* renderTarget) {
void FilamentViewer::destroyRenderTarget(RenderTarget *renderTarget)
{
std::lock_guard lock(_renderMutex);
auto rtDepth = renderTarget->getTexture(RenderTarget::AttachmentPoint::DEPTH);
if(rtDepth) {
if (rtDepth)
{
_engine->destroy(rtDepth);
}
auto rtColor = renderTarget->getTexture(RenderTarget::AttachmentPoint::COLOR);
if(rtColor) {
if (rtColor)
{
_engine->destroy(rtColor);
}
_engine->destroy(renderTarget);
_engine->destroy(renderTarget);
auto it = std::find(_renderTargets.begin(), _renderTargets.end(), renderTarget);
if(it != _renderTargets.end()) {
if (it != _renderTargets.end())
{
_renderTargets.erase(it);
}
}
void FilamentViewer::setRenderTarget(RenderTarget *renderTarget) {
std::lock_guard lock(_renderMutex);
_view->setRenderTarget(renderTarget);
}
void FilamentViewer::destroySwapChain(SwapChain *swapChain)
{
std::lock_guard lock(_renderMutex);
auto it = std::find(_swapChains.begin(), _swapChains.end(), swapChain);
if(it != _swapChains.end()) {
if (it != _swapChains.end())
{
_swapChains.erase(it);
}
_engine->destroy(swapChain);
@@ -850,9 +748,55 @@ namespace thermion_filament
#endif
}
///
///
///
View *FilamentViewer::createView()
{
auto *view = _engine->createView();
view->setLayerEnabled(SceneManager::LAYERS::DEFAULT_ASSETS, true);
view->setLayerEnabled(SceneManager::LAYERS::BACKGROUND, true); // skybox + image
view->setLayerEnabled(SceneManager::LAYERS::OVERLAY, false); // world grid + gizmo
view->setBlendMode(filament::View::BlendMode::TRANSLUCENT);
view->setStencilBufferEnabled(true);
view->setAmbientOcclusionOptions({.enabled = false});
view->setDynamicResolutionOptions({.enabled = false});
#if defined(_WIN32)
view->setStereoscopicOptions({.enabled = true});
#endif
// there's a glitch on certain iGPUs where nothing will render when postprocessing is enabled and bloom is disabled
// set bloom to a small value here
view->setBloomOptions({.strength = 0.01});
view->setDithering(filament::Dithering::NONE);
view->setShadowingEnabled(false);
view->setScreenSpaceRefractionEnabled(false);
view->setPostProcessingEnabled(false);
view->setScene(_scene);
view->setCamera(_mainCamera);
_views.push_back(view);
return view;
}
///
///
///
View *FilamentViewer::getViewAt(int32_t index)
{
Log("Getting view at %d", index);
if (index < _views.size())
{
return _views[index];
}
return nullptr;
}
/// @brief
///
///
void FilamentViewer::clearEntities()
{
_view->setCamera(_mainCamera);
_sceneManager->destroyAll();
}
@@ -867,9 +811,9 @@ namespace thermion_filament
///
///
///
void FilamentViewer::setMainCamera()
void FilamentViewer::setMainCamera(View *view)
{
_view->setCamera(_mainCamera);
view->setCamera(_mainCamera);
}
///
@@ -880,73 +824,6 @@ namespace thermion_filament
return Entity::smuggle(_mainCamera->getEntity());
}
///
/// Sets the active camera to the GLTF camera node specified by [name] (or if null, the first camera found under that node).
/// N.B. Blender will generally export a three-node hierarchy -
/// Camera1->Camera_Orientation->Camera2. The correct name will be the Camera_Orientation.
///
bool FilamentViewer::setCamera(EntityId entityId, const char *cameraName)
{
auto asset = _sceneManager->getAssetByEntityId(entityId);
if (!asset)
{
Log("Failed to find asset under entity id %d.", entityId);
return false;
}
size_t count = asset->getCameraEntityCount();
if (count == 0)
{
Log("No cameras found attached to specified entity.");
return false;
}
const utils::Entity *cameras = asset->getCameraEntities();
utils::Entity target;
if (!cameraName)
{
target = cameras[0];
const char *name = asset->getName(target);
Log("No camera specified, using first camera node found (%s)", name);
}
else
{
for (int j = 0; j < count; j++)
{
const char *name = asset->getName(cameras[j]);
if (strcmp(name, cameraName) == 0)
{
target = cameras[j];
break;
}
}
}
if (target.isNull())
{
Log("Unable to locate camera under name %s ", cameraName);
return false;
}
Camera *camera = _engine->getCameraComponent(target);
if (!camera)
{
Log("Failed to retrieve camera component for target");
return false;
}
_view->setCamera(camera);
const Viewport &vp = _view->getViewport();
const double aspect = (double)vp.width / vp.height;
camera->setScaling({1.0 / aspect, 1.0});
Log("Successfully set view camera to target");
return true;
}
void FilamentViewer::loadSkybox(const char *const skyboxPath)
{
@@ -990,8 +867,8 @@ namespace thermion_filament
callbackData);
_skybox =
filament::Skybox::Builder()
.environment(_skyboxTexture)
.build(*_engine);
.environment(_skyboxTexture)
.build(*_engine);
_skybox->setLayerMask(0xFF, 1u << SceneManager::LAYERS::BACKGROUND);
@@ -1046,13 +923,25 @@ namespace thermion_filament
.build(*_engine);
// Create a copy of the cubemap data
float *pixelData = new float[18] {
r, g, b,
r, g, b,
r, g, b,
r, g, b,
r, g, b,
r, g, b,
float *pixelData = new float[18]{
r,
g,
b,
r,
g,
b,
r,
g,
b,
r,
g,
b,
r,
g,
b,
r,
g,
b,
};
Texture::PixelBufferDescriptor::Callback freeCallback = [](void *buf, size_t, void *data)
@@ -1126,13 +1015,14 @@ namespace thermion_filament
bool FilamentViewer::render(
uint64_t frameTimeInNanos,
SwapChain* swapChain,
View *view,
SwapChain *swapChain,
void *pixelBuffer,
void (*callback)(void *buf, size_t size, void *data),
void *data)
{
if (!_view || !swapChain)
if (!view || !swapChain)
{
return false;
}
@@ -1155,15 +1045,6 @@ namespace thermion_filament
_cumulativeAnimationUpdateTime += tmr.elapsed();
// if a manipulator is active, update the active camera orientation
if (_manipulator)
{
math::double3 eye, target, upward;
Camera &cam = _view->getCamera();
_manipulator->getLookAt(&eye, &target, &upward);
cam.lookAt(eye, target, upward);
}
// Render the scene, unless the renderer wants to skip the frame.
bool beginFrame = _renderer->beginFrame(swapChain, frameTimeInNanos);
if (!beginFrame)
@@ -1174,7 +1055,7 @@ namespace thermion_filament
if (beginFrame)
{
_renderer->render(_view);
_renderer->render(view);
_frameCount++;
@@ -1186,21 +1067,24 @@ namespace thermion_filament
return beginFrame;
}
class CaptureCallbackHandler : public filament::backend::CallbackHandler {
void post(void* user, Callback callback) {
callback(user);
}
class CaptureCallbackHandler : public filament::backend::CallbackHandler
{
void post(void *user, Callback callback)
{
callback(user);
}
};
void FilamentViewer::capture(uint8_t *out, bool useFence, SwapChain* swapChain, void (*onComplete)())
void FilamentViewer::capture(View *view, uint8_t *out, bool useFence, SwapChain *swapChain, void (*onComplete)())
{
if(!swapChain) {
if (!swapChain)
{
Log("NO SWAPCHAIN");
return;
}
Viewport const &vp = _view->getViewport();
Viewport const &vp = view->getViewport();
size_t pixelBufferSize = vp.width * vp.height * 4;
auto *pixelBuffer = new uint8_t[pixelBufferSize];
auto callback = [](void *buf, size_t size, void *data)
@@ -1211,15 +1095,17 @@ namespace thermion_filament
memcpy(out, buf, size);
delete frameCallbackData;
if(callbackPtr) {
if (callbackPtr)
{
void (*callback)(void) = (void (*)(void))callbackPtr;
callback();
}
};
// Create a fence
Fence* fence = nullptr;
if(useFence) {
Fence *fence = nullptr;
if (useFence)
{
fence = _engine->createFence();
}
@@ -1232,7 +1118,7 @@ namespace thermion_filament
Texture::Format::RGBA,
Texture::Type::UBYTE, dispatcher, callback, userData);
_renderer->beginFrame(swapChain, 0);
_renderer->render(_view);
_renderer->render(view);
_renderer->readPixels(0, 0, vp.width, vp.height, std::move(pbd));
_renderer->endFrame();
@@ -1240,20 +1126,22 @@ namespace thermion_filament
_engine->execute();
emscripten_webgl_commit_frame();
#endif
if(fence) {
Fence::waitAndDestroy(fence);
}
if (fence)
{
Fence::waitAndDestroy(fence);
}
}
void FilamentViewer::capture(uint8_t *out, bool useFence, SwapChain* swapChain, RenderTarget* renderTarget, void (*onComplete)())
void FilamentViewer::capture(View *view, uint8_t *out, bool useFence, SwapChain *swapChain, RenderTarget *renderTarget, void (*onComplete)())
{
if(!renderTarget) {
if (!renderTarget)
{
Log("NO SWAPCHAIN");
return;
}
Viewport const &vp = _view->getViewport();
Viewport const &vp = view->getViewport();
size_t pixelBufferSize = vp.width * vp.height * 4;
auto *pixelBuffer = new uint8_t[pixelBufferSize];
auto callback = [](void *buf, size_t size, void *data)
@@ -1264,15 +1152,17 @@ namespace thermion_filament
memcpy(out, buf, size);
delete frameCallbackData;
if(callbackPtr) {
if (callbackPtr)
{
void (*callback)(void) = (void (*)(void))callbackPtr;
callback();
}
};
// Create a fence
Fence* fence = nullptr;
if(useFence) {
Fence *fence = nullptr;
if (useFence)
{
fence = _engine->createFence();
}
@@ -1285,7 +1175,7 @@ namespace thermion_filament
Texture::Format::RGBA,
Texture::Type::UBYTE, dispatcher, callback, userData);
_renderer->beginFrame(swapChain, 0);
_renderer->render(_view);
_renderer->render(view);
_renderer->readPixels(renderTarget, 0, 0, vp.width, vp.height, std::move(pbd));
_renderer->endFrame();
@@ -1293,138 +1183,22 @@ namespace thermion_filament
_engine->execute();
emscripten_webgl_commit_frame();
#endif
if(fence) {
Fence::waitAndDestroy(fence);
}
if (fence)
{
Fence::waitAndDestroy(fence);
}
}
Camera* FilamentViewer::getCamera(EntityId entity) {
Camera *FilamentViewer::getCamera(EntityId entity)
{
return _engine->getCameraComponent(Entity::import(entity));
}
void FilamentViewer::updateViewport(
uint32_t width, uint32_t height)
{
_view->setViewport({0, 0, width, height});
}
void FilamentViewer::setViewFrustumCulling(bool enabled)
{
_view->setFrustumCullingEnabled(enabled);
}
void FilamentViewer::_createManipulator()
{
Camera &cam = _view->getCamera();
math::double3 home = cam.getPosition();
math::double3 up = cam.getUpVector();
auto fv = cam.getForwardVector();
math::double3 target = home + fv;
Viewport const &vp = _view->getViewport();
_manipulator = Manipulator<double>::Builder()
.viewport(vp.width, vp.height)
.upVector(up.x, up.y, up.z)
.zoomSpeed(_zoomSpeed)
.targetPosition(target[0], target[1], target[2])
// only applicable to Mode::ORBIT
.orbitHomePosition(home[0], home[1], home[2])
.orbitSpeed(_orbitSpeedX, _orbitSpeedY)
// only applicable to Mode::FREE_FLIGHT
.flightStartPosition(home[0], home[1], home[2])
.build(_manipulatorMode);
}
void FilamentViewer::setCameraManipulatorOptions(filament::camutils::Mode mode, double orbitSpeedX, double orbitSpeedY, double zoomSpeed)
{
_manipulatorMode = mode;
_orbitSpeedX = orbitSpeedX;
_orbitSpeedY = orbitSpeedY;
_zoomSpeed = zoomSpeed;
}
void FilamentViewer::grabBegin(float x, float y, bool pan)
{
if (!_view || !_mainCamera)
{
Log("View not ready, ignoring grab");
return;
}
if (!_manipulator)
{
_createManipulator();
}
_manipulator->grabBegin(x, y, pan);
}
void FilamentViewer::grabUpdate(float x, float y)
{
if (!_view )
{
Log("View not ready, ignoring grab");
return;
}
if (_manipulator)
{
_manipulator->grabUpdate(x, y);
}
else
{
Log("Error - trying to use a manipulator when one is not available. Ensure you call grabBegin before grabUpdate/grabEnd");
}
}
void FilamentViewer::grabEnd()
{
if (!_view || !_mainCamera )
{
Log("View not ready, ignoring grab");
return;
}
if (_manipulator)
{
_manipulator->grabEnd();
}
else
{
Log("Error - trying to use a manipulator when one is not available. Ensure you call grabBegin before grabUpdate/grabEnd");
}
delete _manipulator;
_manipulator = nullptr;
}
void FilamentViewer::scrollBegin()
{
if (!_manipulator)
{
_createManipulator();
}
}
void FilamentViewer::scrollUpdate(float x, float y, float delta)
{
if (_manipulator)
{
_manipulator->scroll(int(x), int(y), delta);
}
else
{
Log("Error - trying to use a manipulator when one is not available. Ensure you call grabBegin before grabUpdate/grabEnd");
}
}
void FilamentViewer::scrollEnd()
{
delete _manipulator;
_manipulator = nullptr;
}
void FilamentViewer::pick(uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y))
void FilamentViewer::pick(View *view, uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y))
{
_view->pick(x, y, [=](filament::View::PickingQueryResult const &result) {
view->pick(x, y, [=](filament::View::PickingQueryResult const &result)
{
if(_sceneManager->gizmo->isGizmoEntity(result.renderable)) {
Log("Gizmo entity, ignoring");
@@ -1438,24 +1212,23 @@ namespace thermion_filament
if (nonPickableEntities.find(result.renderable) == nonPickableEntities.end()) {
callback(Entity::smuggle(result.renderable), x, y);
}
});
} });
}
void FilamentViewer::unprojectTexture(EntityId entityId, uint8_t* input, uint32_t inputWidth, uint32_t inputHeight, uint8_t* out, uint32_t outWidth, uint32_t outHeight) {
const auto * geometry = _sceneManager->getGeometry(entityId);
if(!geometry->uvs) {
Log("No UVS");
return;
void FilamentViewer::unprojectTexture(EntityId entityId, uint8_t *input, uint32_t inputWidth, uint32_t inputHeight, uint8_t *out, uint32_t outWidth, uint32_t outHeight)
{
const auto *geometry = _sceneManager->getGeometry(entityId);
if (!geometry->uvs)
{
Log("No UVS");
return;
}
UnprojectTexture unproject(geometry, _view->getCamera(), _engine);
// UnprojectTexture unproject(geometry, _view->getCamera(), _engine);
// TODO - check that input dimensions match viewport?
unproject.unproject(utils::Entity::import(entityId), input, out, inputWidth, inputHeight, outWidth, outHeight);
// unproject.unproject(utils::Entity::import(entityId), input, out, inputWidth, inputHeight, outWidth, outHeight);
}
} // namespace thermion_filament

View File

@@ -14,12 +14,10 @@ namespace thermion_filament {
using namespace filament::gltfio;
Gizmo::Gizmo(Engine &engine, View* view, Scene* scene) : _engine(engine)
Gizmo::Gizmo(Engine &engine, Scene* scene) : _engine(engine)
{
_scene = scene;
_view = view;
_camera = &(_view->getCamera());
auto &entityManager = EntityManager::get();
@@ -326,10 +324,10 @@ void Gizmo::unhighlight() {
}
}
void Gizmo::pick(uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y))
void Gizmo::pick(View *view, uint32_t x, uint32_t y, void (*callback)(EntityId entityId, int x, int y))
{
auto handler = new Gizmo::PickCallbackHandler(this, callback);
_view->pick(x, y, [=](filament::View::PickingQueryResult const &result) {
view->pick(x, y, [=](filament::View::PickingQueryResult const &result) {
handler->handle(result);
});
}

View File

@@ -48,13 +48,12 @@ namespace thermion_filament
using namespace filament::gltfio;
using std::unique_ptr;
SceneManager::SceneManager(View *view,
const ResourceLoaderWrapperImpl *const resourceLoaderWrapper,
SceneManager::SceneManager(const ResourceLoaderWrapperImpl *const resourceLoaderWrapper,
Engine *engine,
Scene *scene,
const char *uberArchivePath,
Camera *mainCamera)
: _view(view),
:
_resourceLoaderWrapper(resourceLoaderWrapper),
_engine(engine),
_scene(scene),
@@ -99,21 +98,16 @@ namespace thermion_filament
_collisionComponentManager = new CollisionComponentManager(tm);
_animationComponentManager = new AnimationComponentManager(tm, _engine->getRenderableManager());
gizmo = new Gizmo(*_engine, _view, _scene);
gizmo = new Gizmo(*_engine, _scene);
_gridOverlay = new GridOverlay(*_engine);
_scene->addEntity(_gridOverlay->sphere());
_scene->addEntity(_gridOverlay->grid());
_view->setLayerEnabled(SceneManager::LAYERS::DEFAULT_ASSETS, true);
_view->setLayerEnabled(SceneManager::LAYERS::BACKGROUND, true); // skybox + image
_view->setLayerEnabled(SceneManager::LAYERS::OVERLAY, false); // world grid + gizmo
}
SceneManager::~SceneManager()
{
_view->setScene(nullptr);
_view->setCamera(nullptr);
for(auto camera : _cameras) {
auto entity = camera->getEntity();
_engine->destroyCameraComponent(entity);
@@ -1894,11 +1888,11 @@ namespace thermion_filament
tm.setTransform(transformInstance, newTransform);
}
void SceneManager::queueRelativePositionUpdateFromViewportVector(EntityId entityId, float viewportCoordX, float viewportCoordY)
void SceneManager::queueRelativePositionUpdateFromViewportVector(View* view, EntityId entityId, float viewportCoordX, float viewportCoordY)
{
// Get the camera and viewport
const auto &camera = _view->getCamera();
const auto &vp = _view->getViewport();
const auto &camera = view->getCamera();
const auto &vp = view->getViewport();
// Convert viewport coordinates to NDC space
float ndcX = (2.0f * viewportCoordX) / vp.width - 1.0f;
@@ -2170,10 +2164,10 @@ namespace thermion_filament
rm.setPriority(renderableInstance, priority);
}
Aabb2 SceneManager::getBoundingBox(EntityId entityId)
Aabb2 SceneManager::getBoundingBox(View *view, EntityId entityId)
{
const auto &camera = _view->getCamera();
const auto &viewport = _view->getViewport();
const auto &camera = view->getCamera();
const auto &viewport = view->getViewport();
auto &tcm = _engine->getTransformManager();
auto &rcm = _engine->getRenderableManager();
@@ -2242,11 +2236,6 @@ namespace thermion_filament
return Aabb2{minX, minY, maxX, maxY};
}
void SceneManager::setLayerVisibility(LAYERS layer, bool enabled)
{
_view->setLayerEnabled(layer, enabled);
}
void SceneManager::removeStencilHighlight(EntityId entityId)
{
std::lock_guard lock(_stencilMutex);
@@ -2491,10 +2480,6 @@ EntityId SceneManager::createGeometry(
}
}
void SceneManager::setCamera(Camera* camera) {
_view->setCamera(camera);
}
size_t SceneManager::getCameraCount() {
return _cameras.size() + 1;
}
@@ -2508,11 +2493,6 @@ EntityId SceneManager::createGeometry(
}
return _cameras[index-1];
}
Camera* SceneManager::getActiveCamera() {
auto& camera = _view->getCamera();
return &camera;
}
} // namespace thermion_filament

View File

@@ -0,0 +1,29 @@
#ifdef _WIN32
#pragma comment(lib, "Shlwapi.lib")
#pragma comment(lib, "opengl32.lib")
#endif
#include "ResourceBuffer.hpp"
#include "FilamentViewer.hpp"
#include "filament/LightManager.h"
#include "Log.hpp"
#include "ThreadPool.hpp"
#include <thread>
#include <functional>
#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#endif
using namespace thermion_filament;
extern "C"
{
EMSCRIPTEN_KEEPALIVE void Gizmo_pick(TGizmo *tGizmo, TView *tView, int x, int y, void (*callback)(EntityId entityId, int x, int y))
{
auto *gizmo = reinterpret_cast<Gizmo*>(tGizmo);
auto *view = reinterpret_cast<View*>(tView);
gizmo->pick(view, x, y, callback);
}
}

View File

@@ -0,0 +1,142 @@
#ifdef _WIN32
#pragma comment(lib, "Shlwapi.lib")
#pragma comment(lib, "opengl32.lib")
#endif
#include "ResourceBuffer.hpp"
#include "FilamentViewer.hpp"
#include "filament/LightManager.h"
#include "Log.hpp"
#include "ThreadPool.hpp"
#include <thread>
#include <functional>
#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#endif
using namespace thermion_filament;
extern "C"
{
#include "ThermionDartApi.h"
EMSCRIPTEN_KEEPALIVE void View_updateViewport(TView *tView, uint32_t width, uint32_t height)
{
auto view = reinterpret_cast<View *>(tView);
view->setViewport({0, 0, width, height});
}
EMSCRIPTEN_KEEPALIVE void View_setRenderTarget(TView *tView, TRenderTarget *tRenderTarget)
{
auto view = reinterpret_cast<View *>(tView);
auto renderTarget = reinterpret_cast<RenderTarget *>(tRenderTarget);
view->setRenderTarget(renderTarget);
}
EMSCRIPTEN_KEEPALIVE void View_setFrustumCullingEnabled(TView *tView, bool enabled)
{
auto view = reinterpret_cast<View *>(tView);
view->setFrustumCullingEnabled(enabled);
}
EMSCRIPTEN_KEEPALIVE void View_setPostProcessing(TView *tView, bool enabled)
{
auto view = reinterpret_cast<View *>(tView);
view->setPostProcessingEnabled(enabled);
}
EMSCRIPTEN_KEEPALIVE void View_setShadowsEnabled(TView *tView, bool enabled)
{
auto view = reinterpret_cast<View *>(tView);
view->setShadowingEnabled(enabled);
}
EMSCRIPTEN_KEEPALIVE void View_setShadowType(TView *tView, ShadowType shadowType)
{
auto view = reinterpret_cast<View *>(tView);
view->setShadowType(shadowType);
}
EMSCRIPTEN_KEEPALIVE void View_setSoftShadowOptions(TView *tView, float penumbraScale, float penumbraRatioScale)
{
auto view = reinterpret_cast<View *>(tView);
SoftShadowOptions opts;
opts.penumbraRatioScale = penumbraRatioScale;
opts.penumbraScale = penumbraScale;
view->setSoftShadowOptions(opts);
}
EMSCRIPTEN_KEEPALIVE void View_setBloom(TView *tView, float strength)
{
auto view = reinterpret_cast<View *>(tView);
#ifndef __EMSCRIPTEN__
decltype(view->getBloomOptions()) opts;
opts.enabled = true;
opts.strength = strength;
view->setBloomOptions(opts);
#endif
}
EMSCRIPTEN_KEEPALIVE void View_setToneMapping(TView *tView, TEngine *tEngine, int toneMapping)
{
auto view = reinterpret_cast<View *>(tView);
auto engine = reinterpret_cast<Engine *>(tEngine);
ToneMapper *tm;
switch (toneMapping)
{
case ToneMapping::ACES:
Log("Setting tone mapping to ACES");
tm = new ACESToneMapper();
break;
case ToneMapping::LINEAR:
Log("Setting tone mapping to Linear");
tm = new LinearToneMapper();
break;
case ToneMapping::FILMIC:
Log("Setting tone mapping to Filmic");
tm = new FilmicToneMapper();
break;
default:
Log("ERROR: Unsupported tone mapping");
return;
}
auto newColorGrading = ColorGrading::Builder().toneMapper(tm).build(*engine);
auto oldColorGrading = view->getColorGrading();
view->setColorGrading(newColorGrading);
if (oldColorGrading)
{
engine->destroy(oldColorGrading);
}
delete tm;
}
void View_setAntiAliasing(TView *tView, bool msaa, bool fxaa, bool taa)
{
auto view = reinterpret_cast<View *>(tView);
View::MultiSampleAntiAliasingOptions multiSampleAntiAliasingOptions;
multiSampleAntiAliasingOptions.enabled = msaa;
view->setMultiSampleAntiAliasingOptions(multiSampleAntiAliasingOptions);
TemporalAntiAliasingOptions taaOpts;
taaOpts.enabled = taa;
view->setTemporalAntiAliasingOptions(taaOpts);
view->setAntiAliasing(fxaa ? AntiAliasing::FXAA : AntiAliasing::NONE);
}
EMSCRIPTEN_KEEPALIVE void View_setLayerEnabled(TView* tView, int layer, bool enabled) {
auto view = reinterpret_cast<View *>(tView);
view->setLayerEnabled(layer, enabled);
}
EMSCRIPTEN_KEEPALIVE void View_setCamera(TView *tView, TCamera *tCamera) {
auto view = reinterpret_cast<View *>(tView);
auto *camera = reinterpret_cast<Camera *>(tCamera);
view->setCamera(camera);
}
}

View File

@@ -48,32 +48,28 @@ extern "C"
{
const auto *loaderImpl = new ResourceLoaderWrapperImpl((ResourceLoaderWrapper *)loader);
auto viewer = new FilamentViewer(context, loaderImpl, platform, uberArchivePath);
return reinterpret_cast<TViewer*>(viewer);
return reinterpret_cast<TViewer *>(viewer);
}
EMSCRIPTEN_KEEPALIVE TEngine *Viewer_getEngine(TViewer* viewer) {
auto* engine = reinterpret_cast<FilamentViewer*>(viewer)->getEngine();
return reinterpret_cast<TEngine*>(engine);
EMSCRIPTEN_KEEPALIVE TEngine *Viewer_getEngine(TViewer *viewer)
{
auto *engine = reinterpret_cast<FilamentViewer *>(viewer)->getEngine();
return reinterpret_cast<TEngine *>(engine);
}
EMSCRIPTEN_KEEPALIVE TRenderTarget* Viewer_createRenderTarget(TViewer *tViewer, intptr_t texture, uint32_t width, uint32_t height)
EMSCRIPTEN_KEEPALIVE TRenderTarget *Viewer_createRenderTarget(TViewer *tViewer, intptr_t texture, uint32_t width, uint32_t height)
{
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
auto renderTarget = viewer->createRenderTarget(texture, width, height);
return reinterpret_cast<TRenderTarget*>(renderTarget);
return reinterpret_cast<TRenderTarget *>(renderTarget);
}
EMSCRIPTEN_KEEPALIVE void Viewer_destroyRenderTarget(TViewer *tViewer, TRenderTarget* tRenderTarget) {
EMSCRIPTEN_KEEPALIVE void Viewer_destroyRenderTarget(TViewer *tViewer, TRenderTarget *tRenderTarget)
{
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
auto renderTarget = reinterpret_cast<RenderTarget*>(tRenderTarget);
auto renderTarget = reinterpret_cast<RenderTarget *>(tRenderTarget);
viewer->destroyRenderTarget(renderTarget);
}
EMSCRIPTEN_KEEPALIVE void Viewer_setRenderTarget(TViewer *tViewer, TRenderTarget* tRenderTarget) {
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
auto renderTarget = reinterpret_cast<RenderTarget*>(tRenderTarget);
viewer->setRenderTarget(renderTarget);
}
EMSCRIPTEN_KEEPALIVE void destroy_filament_viewer(TViewer *viewer)
{
@@ -92,23 +88,14 @@ extern "C"
EMSCRIPTEN_KEEPALIVE void set_background_image(TViewer *viewer, const char *path, bool fillHeight)
{
((FilamentViewer *)viewer)->setBackgroundImage(path, fillHeight);
((FilamentViewer *)viewer)->setBackgroundImage(path, fillHeight, 100, 100);
}
EMSCRIPTEN_KEEPALIVE void set_background_image_position(TViewer *viewer, float x, float y, bool clamp)
{
((FilamentViewer *)viewer)->setBackgroundImagePosition(x, y, clamp);
((FilamentViewer *)viewer)->setBackgroundImagePosition(x, y, clamp, 100, 100);
}
EMSCRIPTEN_KEEPALIVE void set_tone_mapping(TViewer *viewer, int toneMapping)
{
((FilamentViewer *)viewer)->setToneMapping((ToneMapping)toneMapping);
}
EMSCRIPTEN_KEEPALIVE void set_bloom(TViewer *viewer, float strength)
{
((FilamentViewer *)viewer)->setBloom(strength);
}
EMSCRIPTEN_KEEPALIVE void load_skybox(TViewer *viewer, const char *skyboxPath)
{
@@ -221,9 +208,11 @@ extern "C"
return ((SceneManager *)sceneManager)->loadGltf(assetPath, relativePath, keepData);
}
EMSCRIPTEN_KEEPALIVE void set_main_camera(TViewer *viewer)
EMSCRIPTEN_KEEPALIVE void Viewer_setMainCamera(TViewer *tViewer, TView *tView)
{
return ((FilamentViewer *)viewer)->setMainCamera();
auto *viewer = reinterpret_cast<FilamentViewer*>(tViewer);
auto *view = reinterpret_cast<View*>(tView);
viewer->setMainCamera(view);
}
EMSCRIPTEN_KEEPALIVE EntityId get_main_camera(TViewer *viewer)
@@ -231,11 +220,6 @@ extern "C"
return ((FilamentViewer *)viewer)->getMainCamera();
}
EMSCRIPTEN_KEEPALIVE bool set_camera(TViewer *viewer, EntityId asset, const char *nodeName)
{
return ((FilamentViewer *)viewer)->setCamera(asset, nodeName);
}
EMSCRIPTEN_KEEPALIVE float get_camera_fov(TCamera *camera, bool horizontal)
{
auto cam = reinterpret_cast<filament::Camera *>(camera);
@@ -334,15 +318,7 @@ extern "C"
return array;
}
EMSCRIPTEN_KEEPALIVE void set_camera_manipulator_options(TViewer *viewer, _ManipulatorMode mode, double orbitSpeedX, double orbitSpeedY, double zoomSpeed)
{
((FilamentViewer *)viewer)->setCameraManipulatorOptions((filament::camutils::Mode)mode, orbitSpeedX, orbitSpeedY, zoomSpeed);
}
EMSCRIPTEN_KEEPALIVE void set_view_frustum_culling(TViewer *viewer, bool enabled)
{
((FilamentViewer *)viewer)->setViewFrustumCulling(enabled);
}
EMSCRIPTEN_KEEPALIVE void set_camera_focus_distance(TCamera *camera, float distance)
{
@@ -365,20 +341,23 @@ extern "C"
EMSCRIPTEN_KEEPALIVE bool Viewer_render(
TViewer *tViewer,
TView *tView,
TSwapChain *tSwapChain,
uint64_t frameTimeInNanos,
void *pixelBuffer,
void (*callback)(void *buf, size_t size, void *data),
void *data)
{
auto swapChain = reinterpret_cast<SwapChain*>(tSwapChain);
auto viewer = reinterpret_cast<FilamentViewer*>(tViewer);
return viewer->render(frameTimeInNanos, swapChain, pixelBuffer, callback, data);
auto swapChain = reinterpret_cast<SwapChain *>(tSwapChain);
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
auto *view = reinterpret_cast<View*>(tView);
return viewer->render(frameTimeInNanos, view, swapChain, pixelBuffer, callback, data);
}
EMSCRIPTEN_KEEPALIVE void Viewer_capture(
TViewer *tViewer,
TSwapChain* tSwapChain,
TView *tView,
TSwapChain *tSwapChain,
uint8_t *pixelBuffer,
void (*callback)(void))
{
@@ -387,14 +366,16 @@ extern "C"
#else
bool useFence = false;
#endif
auto swapChain = reinterpret_cast<SwapChain*>(tSwapChain);
auto viewer = reinterpret_cast<FilamentViewer*>(tViewer);
viewer->capture(pixelBuffer, useFence, swapChain, callback);
auto swapChain = reinterpret_cast<SwapChain *>(tSwapChain);
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
auto *view = reinterpret_cast<View*>(tView);
viewer->capture(view, pixelBuffer, useFence, swapChain, callback);
};
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderTarget(
TViewer *tViewer,
TSwapChain* tSwapChain,
TView *tView,
TSwapChain *tSwapChain,
TRenderTarget *tRenderTarget,
uint8_t *pixelBuffer,
void (*callback)(void))
@@ -404,10 +385,11 @@ extern "C"
#else
bool useFence = false;
#endif
auto swapChain = reinterpret_cast<SwapChain*>(tSwapChain);
auto renderTarget = reinterpret_cast<RenderTarget*>(tRenderTarget);
auto viewer = reinterpret_cast<FilamentViewer*>(tViewer);
viewer->capture(pixelBuffer, useFence, swapChain, renderTarget, callback);
auto swapChain = reinterpret_cast<SwapChain *>(tSwapChain);
auto renderTarget = reinterpret_cast<RenderTarget *>(tRenderTarget);
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
auto *view = reinterpret_cast<View*>(tView);
viewer->capture(view, pixelBuffer, useFence, swapChain, renderTarget, callback);
};
EMSCRIPTEN_KEEPALIVE void set_frame_interval(
@@ -417,59 +399,41 @@ extern "C"
((FilamentViewer *)viewer)->setFrameInterval(frameInterval);
}
EMSCRIPTEN_KEEPALIVE void Viewer_destroySwapChain(TViewer *tViewer, TSwapChain* tSwapChain)
EMSCRIPTEN_KEEPALIVE void Viewer_destroySwapChain(TViewer *tViewer, TSwapChain *tSwapChain)
{
auto viewer = reinterpret_cast<FilamentViewer*>(tViewer);
auto swapChain = reinterpret_cast<SwapChain*>(tSwapChain);
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
auto swapChain = reinterpret_cast<SwapChain *>(tSwapChain);
viewer->destroySwapChain(swapChain);
}
EMSCRIPTEN_KEEPALIVE TSwapChain *Viewer_createSwapChain(TViewer *tViewer, const void *const window, uint32_t width, uint32_t height) {
auto viewer = reinterpret_cast<FilamentViewer*>(tViewer);
EMSCRIPTEN_KEEPALIVE TSwapChain *Viewer_createSwapChain(TViewer *tViewer, const void *const window, uint32_t width, uint32_t height)
{
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
auto swapChain = viewer->createSwapChain(window, width, height);
return reinterpret_cast<TSwapChain*>(swapChain);
return reinterpret_cast<TSwapChain *>(swapChain);
}
EMSCRIPTEN_KEEPALIVE void update_viewport(TViewer *viewer, uint32_t width, uint32_t height)
EMSCRIPTEN_KEEPALIVE TView *Viewer_createView(TViewer *tViewer)
{
return ((FilamentViewer *)viewer)->updateViewport(width, height);
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
auto view = viewer->createView();
return reinterpret_cast<TView *>(view);
}
EMSCRIPTEN_KEEPALIVE void scroll_update(TViewer *viewer, float x, float y, float delta)
EMSCRIPTEN_KEEPALIVE TView *Viewer_getViewAt(TViewer *tViewer, int32_t index)
{
((FilamentViewer *)viewer)->scrollUpdate(x, y, delta);
auto viewer = reinterpret_cast<FilamentViewer *>(tViewer);
auto view = viewer->getViewAt(index);
return reinterpret_cast<TView *>(view);
}
EMSCRIPTEN_KEEPALIVE void scroll_begin(TViewer *viewer)
{
((FilamentViewer *)viewer)->scrollBegin();
}
EMSCRIPTEN_KEEPALIVE void scroll_end(TViewer *viewer)
EMSCRIPTEN_KEEPALIVE TSceneManager *Viewer_getSceneManager(TViewer *tViewer)
{
((FilamentViewer *)viewer)->scrollEnd();
}
EMSCRIPTEN_KEEPALIVE void grab_begin(TViewer *viewer, float x, float y, bool pan)
{
((FilamentViewer *)viewer)->grabBegin(x, y, pan);
}
EMSCRIPTEN_KEEPALIVE void grab_update(TViewer *viewer, float x, float y)
{
((FilamentViewer *)viewer)->grabUpdate(x, y);
}
EMSCRIPTEN_KEEPALIVE void grab_end(TViewer *viewer)
{
((FilamentViewer *)viewer)->grabEnd();
}
EMSCRIPTEN_KEEPALIVE TSceneManager* Viewer_getSceneManager(TViewer *tViewer)
{
auto * viewer = reinterpret_cast<FilamentViewer*>(tViewer);
auto * sceneManager = viewer->getSceneManager();
return reinterpret_cast<TSceneManager*>(sceneManager);
auto *viewer = reinterpret_cast<FilamentViewer *>(tViewer);
auto *sceneManager = viewer->getSceneManager();
return reinterpret_cast<TSceneManager *>(sceneManager);
}
EMSCRIPTEN_KEEPALIVE void apply_weights(
@@ -529,31 +493,6 @@ extern "C"
((SceneManager *)sceneManager)->addBoneAnimation(asset, skinIndex, boneIndex, frameData, numFrames, frameLengthInMs, fadeOutInSecs, fadeInInSecs, maxDelta);
}
EMSCRIPTEN_KEEPALIVE void set_post_processing(TViewer *viewer, bool enabled)
{
((FilamentViewer *)viewer)->setPostProcessing(enabled);
}
EMSCRIPTEN_KEEPALIVE void set_shadows_enabled(TViewer *viewer, bool enabled)
{
((FilamentViewer *)viewer)->setShadowsEnabled(enabled);
}
EMSCRIPTEN_KEEPALIVE void set_shadow_type(TViewer *viewer, int shadowType)
{
((FilamentViewer *)viewer)->setShadowType((ShadowType)shadowType);
}
EMSCRIPTEN_KEEPALIVE void set_soft_shadow_options(TViewer *viewer, float penumbraScale, float penumbraRatioScale)
{
((FilamentViewer *)viewer)->setSoftShadowOptions(penumbraScale, penumbraRatioScale);
}
EMSCRIPTEN_KEEPALIVE void set_antialiasing(TViewer *viewer, bool msaa, bool fxaa, bool taa)
{
((FilamentViewer *)viewer)->setAntiAliasing(msaa, fxaa, taa);
}
EMSCRIPTEN_KEEPALIVE EntityId get_bone(TSceneManager *sceneManager,
EntityId entityId,
int skinIndex,
@@ -737,6 +676,17 @@ extern "C"
}
}
EMSCRIPTEN_KEEPALIVE TCamera* SceneManager_getCameraByName(TSceneManager *tSceneManager, EntityId entityId, const char* name) {
auto *sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
return nullptr;
}
EMSCRIPTEN_KEEPALIVE TGizmo* SceneManager_getGizmo(TSceneManager *tSceneManager) {
auto *sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
auto *gizmo = sceneManager->gizmo;
return reinterpret_cast<TGizmo*>(gizmo);
}
EMSCRIPTEN_KEEPALIVE bool SceneManager_setTransform(TSceneManager *sceneManager, EntityId entityId, const double *const transform)
{
auto matrix = math::mat4(
@@ -757,25 +707,27 @@ extern "C"
return ((SceneManager *)sceneManager)->setTransform(entityId, matrix);
}
EMSCRIPTEN_KEEPALIVE void SceneManager_queueTransformUpdates(TSceneManager *tSceneManager, EntityId* entities, const double* const transforms, int numEntities) {
auto * sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
EMSCRIPTEN_KEEPALIVE void SceneManager_queueTransformUpdates(TSceneManager *tSceneManager, EntityId *entities, const double *const transforms, int numEntities)
{
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
math::mat4 matrices[numEntities];
for(int i = 0; i < numEntities; i++) {
matrices[i] = math::mat4(
transforms[i * 16], transforms[i*16+1], transforms[i*16+2],
transforms[i*16+3],
transforms[i*16+4],
transforms[i*16+5],
transforms[i*16+6],
transforms[i*16+7],
transforms[i*16+8],
transforms[i*16+9],
transforms[i*16+10],
transforms[i*16+11],
transforms[i*16+12],
transforms[i*16+13],
transforms[i*16+14],
transforms[i*16+15]);
for (int i = 0; i < numEntities; i++)
{
matrices[i] = math::mat4(
transforms[i * 16], transforms[i * 16 + 1], transforms[i * 16 + 2],
transforms[i * 16 + 3],
transforms[i * 16 + 4],
transforms[i * 16 + 5],
transforms[i * 16 + 6],
transforms[i * 16 + 7],
transforms[i * 16 + 8],
transforms[i * 16 + 9],
transforms[i * 16 + 10],
transforms[i * 16 + 11],
transforms[i * 16 + 12],
transforms[i * 16 + 13],
transforms[i * 16 + 14],
transforms[i * 16 + 15]);
}
sceneManager->queueTransformUpdates(entities, matrices, numEntities);
}
@@ -833,9 +785,10 @@ extern "C"
((SceneManager *)sceneManager)->setScale(asset, scale);
}
EMSCRIPTEN_KEEPALIVE void queue_position_update_from_viewport_coords(TSceneManager *sceneManager, EntityId entity, float viewportX, float viewportY)
EMSCRIPTEN_KEEPALIVE void queue_position_update_from_viewport_coords(TSceneManager *sceneManager, TView *tView, EntityId entity, float viewportX, float viewportY)
{
((SceneManager *)sceneManager)->queueRelativePositionUpdateFromViewportVector(entity, viewportX, viewportY);
auto *view = reinterpret_cast<View*>(tView);
((SceneManager *)sceneManager)->queueRelativePositionUpdateFromViewportVector(view, entity, viewportX, viewportY);
}
EMSCRIPTEN_KEEPALIVE void stop_animation(TSceneManager *sceneManager, EntityId asset, int index)
@@ -853,9 +806,11 @@ extern "C"
return ((SceneManager *)sceneManager)->reveal(asset, meshName);
}
EMSCRIPTEN_KEEPALIVE void filament_pick(TViewer *viewer, int x, int y, void (*callback)(EntityId entityId, int x, int y))
EMSCRIPTEN_KEEPALIVE void filament_pick(TViewer *tViewer, TView* tView, int x, int y, void (*callback)(EntityId entityId, int x, int y))
{
((FilamentViewer *)viewer)->pick(static_cast<uint32_t>(x), static_cast<uint32_t>(y), callback);
auto *viewer = reinterpret_cast<FilamentViewer*>(tViewer);
auto *view = reinterpret_cast<View*>(tView);
((FilamentViewer *)viewer)->pick(view, static_cast<uint32_t>(x), static_cast<uint32_t>(y), callback);
}
EMSCRIPTEN_KEEPALIVE const char *get_name_for_entity(TSceneManager *sceneManager, const EntityId entityId)
@@ -965,28 +920,26 @@ extern "C"
out[3] = Entity::smuggle(gizmo->center());
}
EMSCRIPTEN_KEEPALIVE Aabb2 get_bounding_box(TSceneManager *sceneManager, EntityId entity)
EMSCRIPTEN_KEEPALIVE Aabb2 get_bounding_box(TSceneManager *sceneManager, TView *tView, EntityId entity)
{
return ((SceneManager *)sceneManager)->getBoundingBox(entity);
auto view = reinterpret_cast<View*>(tView);
return ((SceneManager *)sceneManager)->getBoundingBox(view, entity);
}
EMSCRIPTEN_KEEPALIVE void get_bounding_box_to_out(TSceneManager *sceneManager, EntityId entity, float *minX, float *minY, float *maxX, float *maxY)
EMSCRIPTEN_KEEPALIVE void get_bounding_box_to_out(TSceneManager *sceneManager, TView *tView, EntityId entity, float *minX, float *minY, float *maxX, float *maxY)
{
auto box = ((SceneManager *)sceneManager)->getBoundingBox(entity);
auto view = reinterpret_cast<View*>(tView);
auto box = ((SceneManager *)sceneManager)->getBoundingBox(view, entity);
*minX = box.minX;
*minY = box.minY;
*maxX = box.maxX;
*maxY = box.maxY;
}
EMSCRIPTEN_KEEPALIVE void set_visibility_layer(TSceneManager *sceneManager, EntityId entity, int layer) {
((SceneManager*)sceneManager)->setVisibilityLayer(entity, layer);
}
EMSCRIPTEN_KEEPALIVE void set_layer_visibility(TSceneManager *sceneManager, int layer, bool visible)
EMSCRIPTEN_KEEPALIVE void SceneManager_setVisibilityLayer(TSceneManager *tSceneManager, EntityId entity, int layer)
{
((SceneManager *)sceneManager)->setLayerVisibility((SceneManager::LAYERS)layer, visible);
auto *sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
sceneManager->setVisibilityLayer(entity, layer);
}
EMSCRIPTEN_KEEPALIVE void thermion_flutter_free(void *ptr)
@@ -994,11 +947,6 @@ extern "C"
free(ptr);
}
EMSCRIPTEN_KEEPALIVE void pick_gizmo(TSceneManager *sceneManager, int x, int y, void (*callback)(EntityId entityId, int x, int y))
{
((SceneManager *)sceneManager)->gizmo->pick(x, y, callback);
}
EMSCRIPTEN_KEEPALIVE void set_gizmo_visibility(TSceneManager *sceneManager, bool visible)
{
((SceneManager *)sceneManager)->gizmo->setVisibility(visible);
@@ -1019,9 +967,10 @@ extern "C"
((SceneManager *)sceneManager)->setMaterialProperty(entity, materialIndex, property, value);
}
EMSCRIPTEN_KEEPALIVE TMaterialInstance* get_material_instance_at(TSceneManager *sceneManager, EntityId entity, int materialIndex) {
EMSCRIPTEN_KEEPALIVE TMaterialInstance *get_material_instance_at(TSceneManager *sceneManager, EntityId entity, int materialIndex)
{
auto instance = ((SceneManager *)sceneManager)->getMaterialInstanceAt(entity, materialIndex);
return reinterpret_cast<TMaterialInstance*>(instance);
return reinterpret_cast<TMaterialInstance *>(instance);
}
EMSCRIPTEN_KEEPALIVE void set_material_property_int(TSceneManager *sceneManager, EntityId entity, int materialIndex, const char *property, int32_t value)
@@ -1030,7 +979,7 @@ extern "C"
}
EMSCRIPTEN_KEEPALIVE void set_material_property_float4(TSceneManager *sceneManager, EntityId entity, int materialIndex, const char *property, double4 value)
{
{
filament::math::float4 filamentValue;
filamentValue.x = static_cast<float32_t>(value.x);
filamentValue.y = static_cast<float32_t>(value.y);
@@ -1039,7 +988,7 @@ extern "C"
((SceneManager *)sceneManager)->setMaterialProperty(entity, materialIndex, property, filamentValue);
}
EMSCRIPTEN_KEEPALIVE void unproject_texture(TViewer *viewer, EntityId entity, uint8_t* input, uint32_t inputWidth, uint32_t inputHeight, uint8_t *out, uint32_t outWidth, uint32_t outHeight)
EMSCRIPTEN_KEEPALIVE void unproject_texture(TViewer *viewer, EntityId entity, uint8_t *input, uint32_t inputWidth, uint32_t inputHeight, uint8_t *out, uint32_t outWidth, uint32_t outHeight)
{
((FilamentViewer *)viewer)->unprojectTexture(entity, input, inputWidth, inputHeight, out, outWidth, outHeight);
}
@@ -1059,146 +1008,154 @@ extern "C"
((SceneManager *)sceneManager)->destroyTexture(reinterpret_cast<Texture *>(texture));
}
EMSCRIPTEN_KEEPALIVE TMaterialInstance *create_material_instance(TSceneManager *sceneManager, TMaterialKey materialConfig)
{
EMSCRIPTEN_KEEPALIVE TMaterialInstance* create_material_instance(TSceneManager *sceneManager, TMaterialKey materialConfig)
{
filament::gltfio::MaterialKey config;
memset(&config, 0, sizeof(MaterialKey));
filament::gltfio::MaterialKey config;
memset(&config, 0, sizeof(MaterialKey));
// Set and log each field
config.unlit = materialConfig.unlit;
config.doubleSided = materialConfig.doubleSided;
config.useSpecularGlossiness = materialConfig.useSpecularGlossiness;
config.alphaMode = static_cast<filament::gltfio::AlphaMode>(materialConfig.alphaMode);
config.hasBaseColorTexture = materialConfig.hasBaseColorTexture;
config.hasClearCoat = materialConfig.hasClearCoat;
config.hasClearCoatNormalTexture = materialConfig.hasClearCoatNormalTexture;
config.hasClearCoatRoughnessTexture = materialConfig.hasClearCoatRoughnessTexture;
config.hasEmissiveTexture = materialConfig.hasEmissiveTexture;
config.hasIOR = materialConfig.hasIOR;
config.hasMetallicRoughnessTexture = materialConfig.hasMetallicRoughnessTexture;
config.hasNormalTexture = materialConfig.hasNormalTexture;
config.hasOcclusionTexture = materialConfig.hasOcclusionTexture;
config.hasSheen = materialConfig.hasSheen;
config.hasSheenColorTexture = materialConfig.hasSheenColorTexture;
config.hasSheenRoughnessTexture = materialConfig.hasSheenRoughnessTexture;
config.hasTextureTransforms = materialConfig.hasTextureTransforms;
config.hasTransmission = materialConfig.hasTransmission;
config.hasTransmissionTexture = materialConfig.hasTransmissionTexture;
config.hasVolume = materialConfig.hasVolume;
config.hasVolumeThicknessTexture = materialConfig.hasVolumeThicknessTexture;
config.baseColorUV = materialConfig.baseColorUV;
config.hasVertexColors = materialConfig.hasVertexColors;
auto materialInstance = ((SceneManager *)sceneManager)->createUbershaderMaterialInstance(config);
return reinterpret_cast<TMaterialInstance*>(materialInstance);
}
EMSCRIPTEN_KEEPALIVE TMaterialInstance *create_unlit_material_instance(TSceneManager *sceneManager) {
auto * instance = ((SceneManager*)sceneManager)->createUnlitMaterialInstance();
return reinterpret_cast<TMaterialInstance*>(instance);
}
EMSCRIPTEN_KEEPALIVE void destroy_material_instance(TSceneManager *sceneManager, TMaterialInstance *instance) {
((SceneManager *)sceneManager)->destroy(reinterpret_cast<MaterialInstance*>(instance));
}
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthWrite(TMaterialInstance* materialInstance, bool enabled) {
reinterpret_cast<MaterialInstance*>(materialInstance)->setDepthWrite(enabled);
}
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthCulling(TMaterialInstance* materialInstance, bool enabled) {
reinterpret_cast<MaterialInstance*>(materialInstance)->setDepthCulling(enabled);
}
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat2(TMaterialInstance* materialInstance, const char* propertyName, double x, double y) {
filament::math::float2 data { static_cast<float>(x), static_cast<float>(y) };
reinterpret_cast<MaterialInstance*>(materialInstance)->setParameter(propertyName, data);
}
EMSCRIPTEN_KEEPALIVE void Camera_setCustomProjectionWithCulling(TCamera* tCamera, double4x4 projectionMatrix, double near, double far) {
auto * camera = reinterpret_cast<Camera*>(tCamera);
camera->setCustomProjection(convert_double4x4_to_mat4(projectionMatrix), near, far);
}
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getModelMatrix(TCamera* tCamera) {
auto * camera = reinterpret_cast<Camera*>(tCamera);
return convert_mat4_to_double4x4(camera->getModelMatrix());
}
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getViewMatrix(TCamera *const tCamera) {
auto * camera = reinterpret_cast<Camera*>(tCamera);
return convert_mat4_to_double4x4(camera->getViewMatrix());
}
EMSCRIPTEN_KEEPALIVE EntityId Camera_getEntity(TCamera* tCamera) {
auto * camera = reinterpret_cast<Camera*>(tCamera);
return Entity::smuggle(camera->getEntity());
}
EMSCRIPTEN_KEEPALIVE double Camera_getFocalLength(TCamera *const tCamera) {
auto * camera = reinterpret_cast<Camera*>(tCamera);
return camera->getFocalLength();
}
EMSCRIPTEN_KEEPALIVE double Camera_getNear(TCamera *const tCamera) {
auto * camera = reinterpret_cast<Camera*>(tCamera);
return camera->getNear();
}
EMSCRIPTEN_KEEPALIVE double Camera_getCullingFar(TCamera *const tCamera) {
auto * camera = reinterpret_cast<Camera*>(tCamera);
return camera->getCullingFar();
}
EMSCRIPTEN_KEEPALIVE TCamera *Engine_getCameraComponent(TEngine* tEngine, EntityId entityId) {
auto * engine = reinterpret_cast<Engine*>(tEngine);
auto * camera = engine->getCameraComponent(utils::Entity::import(entityId));
return reinterpret_cast<TCamera*>(camera);
}
EMSCRIPTEN_KEEPALIVE void Engine_setTransform(TEngine* tEngine, EntityId entity, double4x4 transform) {
auto * engine = reinterpret_cast<Engine*>(tEngine);
auto& transformManager = engine->getTransformManager();
auto transformInstance = transformManager.getInstance(utils::Entity::import(entity));
if(!transformInstance.isValid()) {
Log("Transform instance not valid");
// Set and log each field
config.unlit = materialConfig.unlit;
config.doubleSided = materialConfig.doubleSided;
config.useSpecularGlossiness = materialConfig.useSpecularGlossiness;
config.alphaMode = static_cast<filament::gltfio::AlphaMode>(materialConfig.alphaMode);
config.hasBaseColorTexture = materialConfig.hasBaseColorTexture;
config.hasClearCoat = materialConfig.hasClearCoat;
config.hasClearCoatNormalTexture = materialConfig.hasClearCoatNormalTexture;
config.hasClearCoatRoughnessTexture = materialConfig.hasClearCoatRoughnessTexture;
config.hasEmissiveTexture = materialConfig.hasEmissiveTexture;
config.hasIOR = materialConfig.hasIOR;
config.hasMetallicRoughnessTexture = materialConfig.hasMetallicRoughnessTexture;
config.hasNormalTexture = materialConfig.hasNormalTexture;
config.hasOcclusionTexture = materialConfig.hasOcclusionTexture;
config.hasSheen = materialConfig.hasSheen;
config.hasSheenColorTexture = materialConfig.hasSheenColorTexture;
config.hasSheenRoughnessTexture = materialConfig.hasSheenRoughnessTexture;
config.hasTextureTransforms = materialConfig.hasTextureTransforms;
config.hasTransmission = materialConfig.hasTransmission;
config.hasTransmissionTexture = materialConfig.hasTransmissionTexture;
config.hasVolume = materialConfig.hasVolume;
config.hasVolumeThicknessTexture = materialConfig.hasVolumeThicknessTexture;
config.baseColorUV = materialConfig.baseColorUV;
config.hasVertexColors = materialConfig.hasVertexColors;
auto materialInstance = ((SceneManager *)sceneManager)->createUbershaderMaterialInstance(config);
return reinterpret_cast<TMaterialInstance *>(materialInstance);
}
transformManager.setTransform(transformInstance, convert_double4x4_to_mat4(transform));
}
EMSCRIPTEN_KEEPALIVE TCamera *SceneManager_createCamera(TSceneManager* tSceneManager) {
auto * sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
return reinterpret_cast<TCamera*>(sceneManager->createCamera());
}
EMSCRIPTEN_KEEPALIVE TMaterialInstance *create_unlit_material_instance(TSceneManager *sceneManager)
{
auto *instance = ((SceneManager *)sceneManager)->createUnlitMaterialInstance();
return reinterpret_cast<TMaterialInstance *>(instance);
}
EMSCRIPTEN_KEEPALIVE void SceneManager_destroyCamera(TSceneManager* tSceneManager, TCamera* tCamera) {
auto * sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
auto * camera = reinterpret_cast<Camera*>(tCamera);
sceneManager->destroyCamera(camera);
}
EMSCRIPTEN_KEEPALIVE void destroy_material_instance(TSceneManager *sceneManager, TMaterialInstance *instance)
{
((SceneManager *)sceneManager)->destroy(reinterpret_cast<MaterialInstance *>(instance));
}
EMSCRIPTEN_KEEPALIVE void SceneManager_setCamera(TSceneManager* tSceneManager, TCamera* tCamera) {
auto * sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
auto * camera = reinterpret_cast<Camera*>(tCamera);
sceneManager->setCamera(camera);
}
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthWrite(TMaterialInstance *materialInstance, bool enabled)
{
reinterpret_cast<MaterialInstance *>(materialInstance)->setDepthWrite(enabled);
}
EMSCRIPTEN_KEEPALIVE size_t SceneManager_getCameraCount(TSceneManager *tSceneManager) {
auto * sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
return sceneManager->getCameraCount();
}
EMSCRIPTEN_KEEPALIVE TCamera* SceneManager_getCameraAt(TSceneManager *tSceneManager, size_t index) {
auto * sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
auto * camera = sceneManager->getCameraAt(index);
return reinterpret_cast<TCamera*>(camera);
}
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthCulling(TMaterialInstance *materialInstance, bool enabled)
{
reinterpret_cast<MaterialInstance *>(materialInstance)->setDepthCulling(enabled);
}
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat2(TMaterialInstance *materialInstance, const char *propertyName, double x, double y)
{
filament::math::float2 data{static_cast<float>(x), static_cast<float>(y)};
reinterpret_cast<MaterialInstance *>(materialInstance)->setParameter(propertyName, data);
}
EMSCRIPTEN_KEEPALIVE void Camera_setCustomProjectionWithCulling(TCamera *tCamera, double4x4 projectionMatrix, double near, double far)
{
auto *camera = reinterpret_cast<Camera *>(tCamera);
camera->setCustomProjection(convert_double4x4_to_mat4(projectionMatrix), near, far);
}
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getModelMatrix(TCamera *tCamera)
{
auto *camera = reinterpret_cast<Camera *>(tCamera);
return convert_mat4_to_double4x4(camera->getModelMatrix());
}
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getViewMatrix(TCamera *const tCamera)
{
auto *camera = reinterpret_cast<Camera *>(tCamera);
return convert_mat4_to_double4x4(camera->getViewMatrix());
}
EMSCRIPTEN_KEEPALIVE EntityId Camera_getEntity(TCamera *tCamera)
{
auto *camera = reinterpret_cast<Camera *>(tCamera);
return Entity::smuggle(camera->getEntity());
}
EMSCRIPTEN_KEEPALIVE double Camera_getFocalLength(TCamera *const tCamera)
{
auto *camera = reinterpret_cast<Camera *>(tCamera);
return camera->getFocalLength();
}
EMSCRIPTEN_KEEPALIVE double Camera_getNear(TCamera *const tCamera)
{
auto *camera = reinterpret_cast<Camera *>(tCamera);
return camera->getNear();
}
EMSCRIPTEN_KEEPALIVE double Camera_getCullingFar(TCamera *const tCamera)
{
auto *camera = reinterpret_cast<Camera *>(tCamera);
return camera->getCullingFar();
}
EMSCRIPTEN_KEEPALIVE TCamera *Engine_getCameraComponent(TEngine *tEngine, EntityId entityId)
{
auto *engine = reinterpret_cast<Engine *>(tEngine);
auto *camera = engine->getCameraComponent(utils::Entity::import(entityId));
return reinterpret_cast<TCamera *>(camera);
}
EMSCRIPTEN_KEEPALIVE void Engine_setTransform(TEngine *tEngine, EntityId entity, double4x4 transform)
{
auto *engine = reinterpret_cast<Engine *>(tEngine);
auto &transformManager = engine->getTransformManager();
auto transformInstance = transformManager.getInstance(utils::Entity::import(entity));
if (!transformInstance.isValid())
{
Log("Transform instance not valid");
}
transformManager.setTransform(transformInstance, convert_double4x4_to_mat4(transform));
}
EMSCRIPTEN_KEEPALIVE TCamera *SceneManager_createCamera(TSceneManager *tSceneManager)
{
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
return reinterpret_cast<TCamera *>(sceneManager->createCamera());
}
EMSCRIPTEN_KEEPALIVE void SceneManager_destroyCamera(TSceneManager *tSceneManager, TCamera *tCamera)
{
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
auto *camera = reinterpret_cast<Camera *>(tCamera);
sceneManager->destroyCamera(camera);
}
EMSCRIPTEN_KEEPALIVE size_t SceneManager_getCameraCount(TSceneManager *tSceneManager)
{
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
return sceneManager->getCameraCount();
}
EMSCRIPTEN_KEEPALIVE TCamera *SceneManager_getCameraAt(TSceneManager *tSceneManager, size_t index)
{
auto *sceneManager = reinterpret_cast<SceneManager *>(tSceneManager);
auto *camera = sceneManager->getCameraAt(index);
return reinterpret_cast<TCamera *>(camera);
}
EMSCRIPTEN_KEEPALIVE TCamera* SceneManager_getActiveCamera(TSceneManager *tSceneManager) {
auto * sceneManager = reinterpret_cast<SceneManager*>(tSceneManager);
auto * camera = sceneManager->getActiveCamera();
return reinterpret_cast<TCamera*>(camera);
}
}

View File

@@ -82,9 +82,10 @@ public:
}
}
void requestFrame(SwapChain* swapChain, void (*callback)())
void requestFrame(TView* tView, TSwapChain* tSwapChain, void (*callback)())
{
this->target = swapChain;
this->target = tSwapChain;
this->view = tView;
this->_requestFrameRenderCallback = callback;
}
@@ -93,7 +94,7 @@ public:
std::unique_lock<std::mutex> lock(_mutex);
if (target)
{
doRender(target);
doRender(view, target);
this->_requestFrameRenderCallback();
target = nullptr;
@@ -176,7 +177,7 @@ public:
fut.wait();
}
bool doRender(SwapChain *swapChain)
bool doRender(TView* tView, TSwapChain *tSwapChain)
{
#ifdef __EMSCRIPTEN__
if (emscripten_is_webgl_context_lost(_context) == EM_TRUE)
@@ -187,8 +188,7 @@ public:
return;
}
#endif
TSwapChain *tSwapChain = reinterpret_cast<TSwapChain*>(swapChain);
auto rendered = Viewer_render(_viewer, tSwapChain, 0, nullptr, nullptr, nullptr);
auto rendered = Viewer_render(_viewer, tView, tSwapChain, 0, nullptr, nullptr, nullptr);
if (_renderCallback)
{
_renderCallback(_renderCallbackOwner);
@@ -218,7 +218,8 @@ public:
}
public:
SwapChain* target;
TSwapChain *target;
TView *view;
private:
void(*_requestFrameRenderCallback)() = nullptr;
@@ -306,7 +307,7 @@ extern "C"
}
EMSCRIPTEN_KEEPALIVE void Viewer_requestFrameRenderThread(TViewer *viewer, TSwapChain* tSwapChain, void(*onComplete)())
EMSCRIPTEN_KEEPALIVE void Viewer_requestFrameRenderThread(TViewer *viewer, TView* view, TSwapChain* tSwapChain, void(*onComplete)())
{
if (!_rl)
{
@@ -314,7 +315,7 @@ extern "C"
}
else
{
_rl->requestFrame(reinterpret_cast<SwapChain*>(tSwapChain), onComplete);
_rl->requestFrame(view, tSwapChain, onComplete);
}
}
@@ -327,24 +328,24 @@ extern "C"
auto fut = _rl->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Viewer_renderRenderThread(TViewer *viewer, TSwapChain *tSwapChain)
EMSCRIPTEN_KEEPALIVE void Viewer_renderRenderThread(TViewer *viewer, TView *tView, TSwapChain *tSwapChain)
{
std::packaged_task<void()> lambda([=]() mutable
{ _rl->doRender(reinterpret_cast<SwapChain*>(tSwapChain)); });
{ _rl->doRender(tView, tSwapChain); });
auto fut = _rl->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderThread(TViewer *viewer, TSwapChain *tSwapChain, uint8_t *pixelBuffer, void (*onComplete)())
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderThread(TViewer *viewer, TView *view, TSwapChain *tSwapChain, uint8_t *pixelBuffer, void (*onComplete)())
{
std::packaged_task<void()> lambda([=]() mutable
{ Viewer_capture(viewer, tSwapChain, pixelBuffer, onComplete); });
{ Viewer_capture(viewer, view, tSwapChain, pixelBuffer, onComplete); });
auto fut = _rl->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderTargetRenderThread(TViewer *viewer, TSwapChain *tSwapChain, TRenderTarget* tRenderTarget, uint8_t *pixelBuffer, void (*onComplete)())
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderTargetRenderThread(TViewer *viewer, TView *view, TSwapChain *tSwapChain, TRenderTarget* tRenderTarget, uint8_t *pixelBuffer, void (*onComplete)())
{
std::packaged_task<void()> lambda([=]() mutable
{ Viewer_captureRenderTarget(viewer, tSwapChain, tRenderTarget, pixelBuffer, onComplete); });
{ Viewer_captureRenderTarget(viewer, view, tSwapChain, tRenderTarget, pixelBuffer, onComplete); });
auto fut = _rl->add_task(lambda);
}
@@ -449,20 +450,7 @@ extern "C"
{ set_background_image_position(viewer, x, y, clamp); });
auto fut = _rl->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void set_tone_mapping_render_thread(TViewer *viewer,
int toneMapping)
{
std::packaged_task<void()> lambda(
[=]
{ set_tone_mapping(viewer, toneMapping); });
auto fut = _rl->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void set_bloom_render_thread(TViewer *viewer, float strength)
{
std::packaged_task<void()> lambda([=]
{ set_bloom(viewer, strength); });
auto fut = _rl->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void load_skybox_render_thread(TViewer *viewer,
const char *skyboxPath,
void (*onComplete)())
@@ -530,22 +518,6 @@ extern "C"
auto fut = _rl->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void set_camera_render_thread(TViewer *viewer, EntityId asset,
const char *nodeName, void (*callback)(bool))
{
std::packaged_task<bool()> lambda(
[=]
{
auto success = set_camera(viewer, asset, nodeName);
#ifdef __EMSCRIPTEN__
MAIN_THREAD_EM_ASM({ moduleArg.dartFilamentResolveCallback($0, $1); }, callback, success);
#else
callback(success);
#endif
return success;
});
auto fut = _rl->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void
get_morph_target_name_render_thread(TSceneManager *sceneManager, EntityId assetEntity,
@@ -637,15 +609,6 @@ extern "C"
auto fut = _rl->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void set_post_processing_render_thread(TViewer *viewer,
bool enabled)
{
std::packaged_task<void()> lambda(
[=]
{ set_post_processing(viewer, enabled); });
auto fut = _rl->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void
get_name_for_entity_render_thread(TSceneManager *sceneManager, const EntityId entityId, void (*callback)(const char *))
{