feat: camera and resizing improvements

This commit is contained in:
Nick Fisher
2024-10-02 16:47:55 +08:00
parent d294938a2c
commit 562ecf2ee5
27 changed files with 840 additions and 613 deletions

View File

@@ -0,0 +1,50 @@
#pragma once
#ifdef __cplusplus
namespace thermion {
extern "C"
{
#endif
#include "ThermionDartApi.h"
enum Projection {
Perspective,
Orthographic
};
// Camera methods
EMSCRIPTEN_KEEPALIVE void set_camera_exposure(TCamera *camera, float aperture, float shutterSpeed, float sensitivity);
EMSCRIPTEN_KEEPALIVE void set_camera_model_matrix(TCamera *camera, double4x4 matrix);
EMSCRIPTEN_KEEPALIVE TCamera *get_camera(TViewer *viewer, EntityId entity);
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_model_matrix(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_view_matrix(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_projection_matrix(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_culling_projection_matrix(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE const double *const get_camera_frustum(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE void set_camera_projection_matrix(TCamera *camera, double4x4 matrix, double near, double far);
EMSCRIPTEN_KEEPALIVE void set_camera_projection_from_fov(TCamera *camera, double fovInDegrees, double aspect, double near, double far, bool horizontal);
EMSCRIPTEN_KEEPALIVE double get_camera_focal_length(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE double Camera_getFocalLength(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE double Camera_getNear(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE double Camera_getCullingFar(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getViewMatrix(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getModelMatrix(TCamera* camera);
EMSCRIPTEN_KEEPALIVE double get_camera_near(TCamera *camera);
EMSCRIPTEN_KEEPALIVE double get_camera_culling_far(TCamera *camera);
EMSCRIPTEN_KEEPALIVE float get_camera_fov(TCamera *camera, bool horizontal);
EMSCRIPTEN_KEEPALIVE void set_camera_focus_distance(TCamera *camera, float focusDistance);
EMSCRIPTEN_KEEPALIVE void Camera_setCustomProjectionWithCulling(TCamera* camera, double4x4 projectionMatrix, double near, double far);
EMSCRIPTEN_KEEPALIVE void Camera_setModelMatrix(TCamera* camera, double4x4 modelMatrix);
EMSCRIPTEN_KEEPALIVE void Camera_setLensProjection(TCamera *camera, double near, double far, double aspect, double focalLength);
EMSCRIPTEN_KEEPALIVE EntityId Camera_getEntity(TCamera* camera);
EMSCRIPTEN_KEEPALIVE void Camera_setProjection(TCamera *const tCamera, Projection projection, double left, double right,
double bottom, double top,
double near, double far);
#ifdef __cplusplus
}
}
#endif

View File

@@ -0,0 +1,27 @@
#pragma once
#include <math/mat4.h>
#include "APIBoundaryTypes.h"
namespace thermion {
// Helper function to convert filament::math::mat4 to double4x4
static double4x4 convert_mat4_to_double4x4(const filament::math::mat4 &mat)
{
return double4x4{
{mat[0][0], mat[0][1], mat[0][2], mat[0][3]},
{mat[1][0], mat[1][1], mat[1][2], mat[1][3]},
{mat[2][0], mat[2][1], mat[2][2], mat[2][3]},
{mat[3][0], mat[3][1], mat[3][2], mat[3][3]},
};
}
// Helper function to convert double4x4 to filament::math::mat4
static filament::math::mat4 convert_double4x4_to_mat4(const double4x4 &d_mat)
{
return filament::math::mat4{
filament::math::float4{float(d_mat.col1[0]), float(d_mat.col1[1]), float(d_mat.col1[2]), float(d_mat.col1[3])},
filament::math::float4{float(d_mat.col2[0]), float(d_mat.col2[1]), float(d_mat.col2[2]), float(d_mat.col2[3])},
filament::math::float4{float(d_mat.col3[0]), float(d_mat.col3[1]), float(d_mat.col3[2]), float(d_mat.col3[3])},
filament::math::float4{float(d_mat.col4[0]), float(d_mat.col4[1]), float(d_mat.col4[2]), float(d_mat.col4[3])}};
}
}

View File

@@ -48,12 +48,15 @@
#include "APIBoundaryTypes.h"
#include "ResourceBuffer.hpp"
#include "ThermionDartAPIUtils.h"
#ifdef __cplusplus
extern "C"
{
#endif
EMSCRIPTEN_KEEPALIVE TViewer *Viewer_create(const void *const context, const void *const loader, void *const platform, const char *uberArchivePath);
EMSCRIPTEN_KEEPALIVE void destroy_filament_viewer(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE TSceneManager *Viewer_getSceneManager(TViewer *viewer);
@@ -93,7 +96,7 @@ extern "C"
EMSCRIPTEN_KEEPALIVE void set_background_image_position(TViewer *viewer, float x, float y, bool clamp);
EMSCRIPTEN_KEEPALIVE void set_background_color(TViewer *viewer, const float r, const float g, const float b, const float a);
EMSCRIPTEN_KEEPALIVE void set_bloom(TViewer *viewer, float strength);
EMSCRIPTEN_KEEPALIVE void load_skybox(TViewer *viewer, const char *skyboxPath);
EMSCRIPTEN_KEEPALIVE void load_ibl(TViewer *viewer, const char *iblPath, float intensity);
EMSCRIPTEN_KEEPALIVE void create_ibl(TViewer *viewer, float r, float g, float b, float intensity);
@@ -123,14 +126,12 @@ extern "C"
EMSCRIPTEN_KEEPALIVE void set_light_position(TViewer *viewer, EntityId light, float x, float y, float z);
EMSCRIPTEN_KEEPALIVE void set_light_direction(TViewer *viewer, EntityId light, float x, float y, float z);
EMSCRIPTEN_KEEPALIVE EntityId load_glb(TSceneManager *sceneManager, const char *assetPath, int numInstances, bool keepData);
EMSCRIPTEN_KEEPALIVE EntityId load_glb_from_buffer(TSceneManager *sceneManager, const void *const data, size_t length, bool keepData, int priority, int layer);
EMSCRIPTEN_KEEPALIVE EntityId load_gltf(TSceneManager *sceneManager, const char *assetPath, const char *relativePath, bool keepData);
EMSCRIPTEN_KEEPALIVE EntityId create_instance(TSceneManager *sceneManager, EntityId id);
EMSCRIPTEN_KEEPALIVE int get_instance_count(TSceneManager *sceneManager, EntityId entityId);
EMSCRIPTEN_KEEPALIVE void get_instances(TSceneManager *sceneManager, EntityId entityId, EntityId *out);
EMSCRIPTEN_KEEPALIVE EntityId get_main_camera(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE void set_view_frustum_culling(TViewer *viewer, bool enabled);
EMSCRIPTEN_KEEPALIVE void set_frame_interval(TViewer *viewer, float interval);
@@ -208,6 +209,7 @@ extern "C"
EMSCRIPTEN_KEEPALIVE TCamera* SceneManager_findCameraByName(TSceneManager* tSceneManager, EntityId entity, const char* name);
EMSCRIPTEN_KEEPALIVE void SceneManager_setVisibilityLayer(TSceneManager *tSceneManager, EntityId entity, int layer);
EMSCRIPTEN_KEEPALIVE TScene* SceneManager_getScene(TSceneManager *tSceneManager);
EMSCRIPTEN_KEEPALIVE EntityId SceneManager_loadGlbFromBuffer(TSceneManager *sceneManager, const uint8_t *const, size_t length, bool keepData, int priority, int layer);
EMSCRIPTEN_KEEPALIVE bool update_bone_matrices(TSceneManager *sceneManager, EntityId entityId);
@@ -225,37 +227,7 @@ extern "C"
EMSCRIPTEN_KEEPALIVE void set_rotation(TSceneManager *sceneManager, EntityId entity, float rads, float x, float y, float z, float w);
EMSCRIPTEN_KEEPALIVE void set_scale(TSceneManager *sceneManager, EntityId entity, float scale);
// Camera methods
EMSCRIPTEN_KEEPALIVE void set_view_frustum_culling(TViewer *viewer, bool enabled);
EMSCRIPTEN_KEEPALIVE void set_camera_exposure(TCamera *camera, float aperture, float shutterSpeed, float sensitivity);
EMSCRIPTEN_KEEPALIVE void set_camera_model_matrix(TCamera *camera, double4x4 matrix);
EMSCRIPTEN_KEEPALIVE TCamera *get_camera(TViewer *viewer, EntityId entity);
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_model_matrix(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_view_matrix(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_projection_matrix(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE double4x4 get_camera_culling_projection_matrix(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE const double *const get_camera_frustum(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE void set_camera_projection_matrix(TCamera *camera, double4x4 matrix, double near, double far);
EMSCRIPTEN_KEEPALIVE void set_camera_projection_from_fov(TCamera *camera, double fovInDegrees, double aspect, double near, double far, bool horizontal);
EMSCRIPTEN_KEEPALIVE double get_camera_focal_length(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE double Camera_getFocalLength(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE double Camera_getNear(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE double Camera_getCullingFar(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getViewMatrix(TCamera *const camera);
EMSCRIPTEN_KEEPALIVE double4x4 Camera_getModelMatrix(TCamera* camera);
EMSCRIPTEN_KEEPALIVE double get_camera_near(TCamera *camera);
EMSCRIPTEN_KEEPALIVE double get_camera_culling_far(TCamera *camera);
EMSCRIPTEN_KEEPALIVE float get_camera_fov(TCamera *camera, bool horizontal);
EMSCRIPTEN_KEEPALIVE void set_camera_focus_distance(TCamera *camera, float focusDistance);
EMSCRIPTEN_KEEPALIVE void Camera_setCustomProjectionWithCulling(TCamera* camera, double4x4 projectionMatrix, double near, double far);
EMSCRIPTEN_KEEPALIVE void Camera_setModelMatrix(TCamera* camera, double4x4 modelMatrix);
EMSCRIPTEN_KEEPALIVE void Camera_setLensProjection(TCamera *camera, double near, double far, double aspect, double focalLength);
EMSCRIPTEN_KEEPALIVE EntityId Camera_getEntity(TCamera* camera);
EMSCRIPTEN_KEEPALIVE TCamera *Engine_getCameraComponent(TEngine *engine, EntityId entity);
EMSCRIPTEN_KEEPALIVE TEntityManager *Engine_getEntityManager(TEngine *engine);
// SceneManager

View File

@@ -2,8 +2,10 @@
#define _DART_FILAMENT_FFI_API_H
#include "ThermionDartApi.h"
#include "TView.h"
#ifdef __cplusplus
namespace thermion {
extern "C"
{
#endif
@@ -33,6 +35,10 @@ extern "C"
void Viewer_captureRenderTargetRenderThread(TViewer *viewer, TView* view, TSwapChain* swapChain, TRenderTarget* renderTarget, uint8_t* out, void (*onComplete)());
void Viewer_requestFrameRenderThread(TViewer *viewer, void(*onComplete)());
void View_setToneMappingRenderThread(TView *tView, TEngine *tEngine, thermion::ToneMapping toneMapping);
void View_setBloomRenderThread(TView *tView, double bloom);
void destroy_filament_viewer_render_thread(TViewer *viewer);
FilamentRenderCallback make_render_callback_fn_pointer(FilamentRenderCallback);
@@ -43,13 +49,11 @@ extern "C"
void clear_background_image_render_thread(TViewer *viewer);
void set_background_image_render_thread(TViewer *viewer, const char *path, bool fillHeight, void (*onComplete)());
void set_background_image_position_render_thread(TViewer *viewer, float x, float y, bool clamp);
void set_tone_mapping_render_thread(TViewer *viewer, int toneMapping);
void set_bloom_render_thread(TViewer *viewer, float strength);
void load_skybox_render_thread(TViewer *viewer, const char *skyboxPath, void (*onComplete)());
void remove_skybox_render_thread(TViewer *viewer);
void SceneManager_loadGlbFromBufferRenderThread(TSceneManager *sceneManager, const uint8_t *const data, size_t length, int numInstances, bool keepData, int priority, int layer, void (*callback)(EntityId));
void load_glb_render_thread(TSceneManager *sceneManager, const char *assetPath, int numInstances, bool keepData, void (*callback)(EntityId));
void load_glb_from_buffer_render_thread(TSceneManager *sceneManager, const uint8_t *const data, size_t length, int numInstances, bool keepData, int priority, int layer, void (*callback)(EntityId));
void load_gltf_render_thread(TSceneManager *sceneManager, const char *assetPath, const char *relativePath, bool keepData, void (*callback)(EntityId));
void create_instance_render_thread(TSceneManager *sceneManager, EntityId entityId, void (*callback)(EntityId));
void remove_entity_render_thread(TViewer *viewer, EntityId asset, void (*callback)());
@@ -103,6 +107,7 @@ extern "C"
#ifdef __cplusplus
}
}
#endif
#endif // _DART_FILAMENT_FFI_API_H

View File

@@ -783,7 +783,6 @@ namespace thermion
///
View *FilamentViewer::getViewAt(int32_t index)
{
Log("Getting view at %d", index);
if (index < _views.size())
{
return _views[index];

View File

@@ -0,0 +1,84 @@
#include <filament/View.h>
#include <filament/Viewport.h>
#include <filament/Engine.h>
#include <filament/ToneMapper.h>
#include <filament/ColorGrading.h>
#include <filament/Camera.h>
#include <utils/Entity.h>
#include "ThermionDartApi.h"
#include "TCamera.h"
#include "ThermionDartAPIUtils.h"
#include "Log.hpp"
#ifdef __cplusplus
namespace thermion
{
extern "C"
{
using namespace filament;
#endif
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 utils::Entity::smuggle(camera->getEntity());
}
EMSCRIPTEN_KEEPALIVE double Camera_getFocalLength(TCamera *const tCamera)
{
auto *camera = reinterpret_cast<Camera *>(tCamera);
return camera->getFocalLength() * 1000.0;
}
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 void Camera_setProjection(TCamera *const tCamera, Projection projection, double left, double right,
double bottom, double top,
double near, double far)
{
auto *camera = reinterpret_cast<Camera *>(tCamera);
filament::Camera::Projection filamentProjection;
switch(projection) {
case Projection::Orthographic:
filamentProjection = filament::Camera::Projection::ORTHO;
case Projection::Perspective:
filamentProjection = filament::Camera::Projection::PERSPECTIVE;
}
camera->setProjection(filamentProjection, left, right, bottom, top, near, far);
}
#ifdef __cplusplus
}
}
#endif

View File

@@ -9,7 +9,6 @@
#include "TView.h"
#include "Log.hpp"
#ifdef __cplusplus
namespace thermion {
extern "C"

View File

@@ -23,27 +23,6 @@ extern "C"
#include "ThermionDartApi.h"
// Helper function to convert filament::math::mat4 to double4x4
static double4x4 convert_mat4_to_double4x4(const filament::math::mat4 &mat)
{
return double4x4{
{mat[0][0], mat[0][1], mat[0][2], mat[0][3]},
{mat[1][0], mat[1][1], mat[1][2], mat[1][3]},
{mat[2][0], mat[2][1], mat[2][2], mat[2][3]},
{mat[3][0], mat[3][1], mat[3][2], mat[3][3]},
};
}
// Helper function to convert double4x4 to filament::math::mat4
static filament::math::mat4 convert_double4x4_to_mat4(const double4x4 &d_mat)
{
return filament::math::mat4{
filament::math::float4{float(d_mat.col1[0]), float(d_mat.col1[1]), float(d_mat.col1[2]), float(d_mat.col1[3])},
filament::math::float4{float(d_mat.col2[0]), float(d_mat.col2[1]), float(d_mat.col2[2]), float(d_mat.col2[3])},
filament::math::float4{float(d_mat.col3[0]), float(d_mat.col3[1]), float(d_mat.col3[2]), float(d_mat.col3[3])},
filament::math::float4{float(d_mat.col4[0]), float(d_mat.col4[1]), float(d_mat.col4[2]), float(d_mat.col4[3])}};
}
EMSCRIPTEN_KEEPALIVE TViewer *Viewer_create(const void *context, const void *const loader, void *const platform, const char *uberArchivePath)
{
const auto *loaderImpl = new ResourceLoaderWrapperImpl((ResourceLoaderWrapper *)loader);
@@ -183,7 +162,7 @@ extern "C"
return ((SceneManager *)sceneManager)->loadGlb(assetPath, numInstances, keepData);
}
EMSCRIPTEN_KEEPALIVE EntityId load_glb_from_buffer(TSceneManager *sceneManager, const void *const data, size_t length, bool keepData, int priority, int layer)
EMSCRIPTEN_KEEPALIVE EntityId SceneManager_loadGlbFromBuffer(TSceneManager *sceneManager, const uint8_t *const data, size_t length, bool keepData, int priority, int layer)
{
return ((SceneManager *)sceneManager)->loadGlbFromBuffer((const uint8_t *)data, length, 1, keepData, priority, layer);
}
@@ -1064,47 +1043,6 @@ extern "C"
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)
{

View File

@@ -1,5 +1,6 @@
#include "ThermionDartRenderThreadApi.h"
#include "FilamentViewer.hpp"
#include "TView.h"
#include "Log.hpp"
#include "ThreadPool.hpp"
#include "filament/LightManager.h"
@@ -328,7 +329,7 @@ extern "C"
auto fut = _rl->add_task(lambda);
}
void load_glb_from_buffer_render_thread(TSceneManager *sceneManager,
void SceneManager_loadGlbFromBufferRenderThread(TSceneManager *sceneManager,
const uint8_t *const data,
size_t length,
int numInstances,
@@ -340,7 +341,7 @@ extern "C"
std::packaged_task<EntityId()> lambda(
[=]() mutable
{
auto entity = load_glb_from_buffer(sceneManager, data, length, keepData, priority, layer);
auto entity = SceneManager_loadGlbFromBuffer(sceneManager, data, length, keepData, priority, layer);
callback(entity);
return entity;
});
@@ -562,6 +563,24 @@ extern "C"
auto fut = _rl->add_task(lambda);
}
void View_setToneMappingRenderThread(TView *tView, TEngine *tEngine, thermion::ToneMapping toneMapping) {
std::packaged_task<void()> lambda(
[=]
{
View_setToneMapping(tView, tEngine, toneMapping);
});
auto fut = _rl->add_task(lambda);
}
void View_setBloomRenderThread(TView *tView, double bloom) {
std::packaged_task<void()> lambda(
[=]
{
View_setBloom(tView, bloom);
});
auto fut = _rl->add_task(lambda);
}
void reset_to_rest_pose_render_thread(TSceneManager *sceneManager, EntityId entityId, void (*callback)())
{
std::packaged_task<void()> lambda(