feature!:

This is a breaking change needed to fully implement instancing and stencil highlighting.

Previously, users would work directly with entities (on the Dart side, ThermionEntity), e.g.

final entity = await viewer.loadGlb("some.glb");

However, Filament "entities" are a lower-level abstraction.

Loading a glTF file, for example, inserts multiple entities into the scene.

For example, each mesh, light, and camera within a glTF asset will be assigned an entity. A top-level (non-renderable) entity will also be created for the glTF asset, which can be used to transform the entire hierarchy.

"Asset" is a better representation for loading/inserting objects into the scene; think of this as a bundle of entities.

Unless you need to work directly with transforms, instancing, materials and renderables, you can work directly with ThermionAsset.
This commit is contained in:
Nick Fisher
2024-11-21 15:04:10 +08:00
parent 9ada6aae64
commit ed444b0615
195 changed files with 18061 additions and 12628 deletions

View File

@@ -33,7 +33,7 @@
#include <chrono>
#include "ResourceBuffer.hpp"
#include "SceneManager.hpp"
#include "scene/SceneManager.hpp"
#include "ThreadPool.hpp"
namespace thermion
@@ -65,9 +65,6 @@ namespace thermion
void rotateIbl(const math::mat3f &matrix);
void createIbl(float r, float g, float b, float intensity);
void removeEntity(EntityId asset);
void clearEntities();
void render(
uint64_t frameTimeInNanos
);
@@ -98,15 +95,6 @@ namespace thermion
void clearBackgroundImage();
void setBackgroundImagePosition(float x, float y, bool clamp, uint32_t width, uint32_t height);
typedef void (*PickCallback)(EntityId entityId, int x, int y, View *view, float depth, float fragX, float fragY, float fragZ);
///
/// Returns true if the specified entity is a gizmo, grid or background image entity.
///
bool isNonPickableEntity(EntityId entityId);
void pick(View *view, uint32_t x, uint32_t y, PickCallback callback);
Engine* getEngine() {
return _engine;
}

View File

@@ -1,111 +0,0 @@
#pragma once
#include <utils/Entity.h>
#include <filament/Engine.h>
#include <filament/Material.h>
#include <filament/MaterialInstance.h>
#include <filament/Scene.h>
#include <filament/Camera.h>
#include <filament/View.h>
#include <filament/Viewport.h>
#include <gltfio/AssetLoader.h>
#include <gltfio/FilamentAsset.h>
#include <gltfio/FilamentInstance.h>
#include <gltfio/ResourceLoader.h>
#include <filament/IndexBuffer.h>
#include <filament/InstanceBuffer.h>
#include "ThermionDartApi.h"
namespace thermion {
using namespace filament;
using namespace utils;
class Gizmo {
enum Axis { X, Y, Z};
public:
Gizmo(Engine *engine, View *view, Scene *scene, Material* material);
~Gizmo();
typedef void (*PickCallback)(EntityId entityId, uint32_t x, uint32_t y, View *view);
Entity x() {
return _entities[0];
};
Entity y() {
return _entities[1];
};
Entity z() {
return _entities[2];
};
Entity center() {
return _entities[3];
};
bool isActive() {
return _isActive;
}
void pick(uint32_t x, uint32_t y, PickCallback callback);
bool isGizmoEntity(Entity entity);
void setVisibility(bool visible);
private:
class PickCallbackHandler {
public:
PickCallbackHandler(Gizmo* gizmo, PickCallback callback) : _gizmo(gizmo), _callback(callback) {};
void handle(filament::View::PickingQueryResult const &result) {
auto x = static_cast<int32_t>(result.fragCoords.x);
auto y= static_cast<int32_t>(result.fragCoords.y);
for(int i = 0; i < 7; i++) {
if(_gizmo->_entities[i] == result.renderable) {
if(i < 4) {
return;
}
_gizmo->highlight(_gizmo->_entities[i - 4]);
_callback(Entity::smuggle(_gizmo->_entities[i - 4]), x, y, _gizmo->_view);
return;
}
}
_gizmo->unhighlight();
_callback(0, x, y, _gizmo->_view);
delete(this);
}
private:
Gizmo* _gizmo;
PickCallback _callback;
};
void createTransparentRectangles();
void highlight(Entity entity);
void unhighlight();
Engine *_engine;
Scene *_scene;
View *_view;
Material* _material;
utils::Entity _entities[7] = { utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity(), utils::Entity() };
MaterialInstance* _materialInstances[7];
math::float4 inactiveColors[3] {
math::float4 { 1.0f, 0.0f, 0.0f, 0.5f },
math::float4 { 0.0f, 1.0f, 0.0f, 0.5f },
math::float4 { 0.0f, 0.0f, 1.0f, 0.5f },
};
math::float4 activeColors[3] {
math::float4 { 1.0f, 0.0f, 0.0f, 1.0f },
math::float4 { 0.0f, 1.0f, 0.0f, 1.0f },
math::float4 { 0.0f, 0.0f, 1.0f, 1.0f },
};
bool _isActive = true;
};
}

View File

@@ -1,6 +1,6 @@
#pragma once
#include <math/mat4.h>
#include "APIBoundaryTypes.h"
#include "c_api/APIBoundaryTypes.h"
namespace thermion {

View File

@@ -1,365 +0,0 @@
#pragma once
#include <mutex>
#include <vector>
#include <memory>
#include <map>
#include <set>
#include <filament/Scene.h>
#include <filament/Camera.h>
#include <filament/View.h>
#include <gltfio/AssetLoader.h>
#include <gltfio/FilamentAsset.h>
#include <gltfio/FilamentInstance.h>
#include <gltfio/ResourceLoader.h>
#include <filament/IndexBuffer.h>
#include <filament/InstanceBuffer.h>
#include <utils/NameComponentManager.h>
#include "tsl/robin_map.h"
#include "APIBoundaryTypes.h"
#include "CustomGeometry.hpp"
#include "Gizmo.hpp"
#include "GridOverlay.hpp"
#include "ResourceBuffer.hpp"
#include "components/CollisionComponentManager.hpp"
#include "components/AnimationComponentManager.hpp"
namespace thermion
{
typedef int32_t EntityId;
using namespace filament;
using namespace filament::gltfio;
using namespace utils;
using std::string;
using std::unique_ptr;
using std::vector;
class SceneManager
{
public:
SceneManager(
const ResourceLoaderWrapperImpl *const loader,
Engine *engine,
Scene *scene,
const char *uberArchivePath,
Camera* mainCamera);
~SceneManager();
enum LAYERS {
DEFAULT_ASSETS = 0,
BACKGROUND = 6,
OVERLAY = 7,
};
class HighlightOverlay {
public:
HighlightOverlay(EntityId id, SceneManager* const sceneManager, Engine* const engine, float r, float g, float b);
~HighlightOverlay();
bool isValid() {
return !_entity.isNull();
}
private:
MaterialInstance* _highlightMaterialInstance = nullptr;
bool _isGeometryEntity = false;
bool _isGltfAsset = false;
FilamentInstance* _newInstance = nullptr;
Entity _entity;
Engine* const _engine;
SceneManager* const _sceneManager;
};
////
/// @brief Load the glTF file from the specified path and adds all entities to the scene.
/// @param uri the path to the asset. Should be either asset:// (representing a Flutter asset), or file:// (representing a filesystem file).
/// @param relativeResourcePath the (relative) path to the asset's resources.
/// @return the glTF entity.
///
EntityId loadGltf(const char *uri, const char *relativeResourcePath, bool keepData = false);
////
/// @brief Load the GLB from the specified path, optionally creating multiple instances.
/// @param uri the path to the asset. Should be either asset:// (representing a Flutter asset), or file:// (representing a filesystem file).
/// @param numInstances the number of instances to create.
/// @return an Entity representing the FilamentAsset associated with the loaded FilamentAsset.
///
EntityId loadGlb(const char *uri, int numInstances, bool keepData);
EntityId loadGlbFromBuffer(const uint8_t *data, size_t length, int numInstances = 1, bool keepData = false, int priority = 4, int layer = 0, bool loadResourcesAsync = false);
EntityId createInstance(EntityId entityId);
void remove(EntityId entity);
void destroyAll();
unique_ptr<vector<string>> getAnimationNames(EntityId entity);
float getAnimationDuration(EntityId entity, int animationIndex);
unique_ptr<vector<string>> getMorphTargetNames(EntityId assetEntityId, EntityId childEntity);
unique_ptr<vector<string>> getBoneNames(EntityId assetEntityId, EntityId childEntity);
void transformToUnitCube(EntityId e);
inline void updateTransform(EntityId e);
void setScale(EntityId e, float scale);
void setPosition(EntityId e, float x, float y, float z);
void setRotation(EntityId e, float rads, float x, float y, float z, float w);
void queueTransformUpdates(EntityId* entities, math::mat4* transforms, int numEntities);
void queueRelativePositionUpdateWorldAxis(EntityId entity, float viewportCoordX, float viewportCoordY, float x, float y, float z);
void queueRelativePositionUpdateFromViewportVector(View* view, EntityId entityId, float viewportCoordX, float viewportCoordY);
const utils::Entity *getCameraEntities(EntityId e);
size_t getCameraEntityCount(EntityId e);
const utils::Entity *getLightEntities(EntityId e) noexcept;
size_t getLightEntityCount(EntityId e) noexcept;
void updateAnimations();
void updateTransforms();
void testCollisions(EntityId entity);
bool setMaterialColor(EntityId e, const char *meshName, int materialInstance, const float r, const float g, const float b, const float a);
bool setMorphAnimationBuffer(
EntityId entityId,
const float *const morphData,
const uint32_t *const morphIndices,
int numMorphTargets,
int numFrames,
float frameLengthInMs);
void clearMorphAnimationBuffer(
EntityId entityId);
bool setMorphTargetWeights(EntityId entityId, const float *const weights, int count);
math::mat4f getLocalTransform(EntityId entityId);
math::mat4f getWorldTransform(EntityId entityId);
EntityId getBone(EntityId entityId, int skinIndex, int boneIndex);
math::mat4f getInverseBindMatrix(EntityId entityId, int skinIndex, int boneIndex);
/// @brief Set the local transform for the bone at boneIndex/skinIndex in the given entity.
/// @param entityId the parent entity
/// @param entityName the name of the mesh under entityId for which the bone will be set.
/// @param skinIndex the index of the joint skin. Currently only 0 is supported.
/// @param boneName the name of the bone
/// @param transform the 4x4 matrix representing the local transform for the bone
/// @return true if the transform was successfully set, false otherwise
bool setBoneTransform(EntityId entityId, int skinIndex, int boneIndex, math::mat4f transform);
/// @brief Immediately start animating the bone at [boneIndex] under the parent instance [entity] at skin [skinIndex].
/// @param entity the mesh entity to animate
/// @param frameData frame data as quaternions
/// @param numFrames the number of frames
/// @param boneName the name of the bone to animate
/// @param frameLengthInMs the length of each frame in ms
/// @return true if the bone animation was successfully enqueued
bool addBoneAnimation(
EntityId parent,
int skinIndex,
int boneIndex,
const float *const frameData,
int numFrames,
float frameLengthInMs,
float fadeOutInSecs,
float fadeInInSecs,
float maxDelta
);
std::unique_ptr<std::vector<math::mat4f>> getBoneRestTranforms(EntityId entityId, int skinIndex);
void resetBones(EntityId entityId);
bool setTransform(EntityId entityId, math::mat4f transform);
bool setTransform(EntityId entityId, math::mat4 transform);
bool updateBoneMatrices(EntityId entityId);
void playAnimation(EntityId e, int index, bool loop, bool reverse, bool replaceActive, float crossfade = 0.3f, float startOffset = 0.0f);
void stopAnimation(EntityId e, int index);
void setMorphTargetWeights(const char *const entityName, float *weights, int count);
Texture* createTexture(const uint8_t* data, size_t length, const char* name);
bool applyTexture(EntityId entityId, Texture *texture, const char* slotName, int materialIndex);
void destroyTexture(Texture* texture);
void setAnimationFrame(EntityId entity, int animationIndex, int animationFrame);
bool hide(EntityId entity, const char *meshName);
bool reveal(EntityId entity, const char *meshName);
const char *getNameForEntity(EntityId entityId);
utils::Entity findChildEntityByName(
EntityId entityId,
const char *entityName);
int getEntityCount(EntityId entity, bool renderableOnly);
void getEntities(EntityId entity, bool renderableOnly, EntityId *out);
const char *getEntityNameAt(EntityId entity, int index, bool renderableOnly);
void addCollisionComponent(EntityId entity, void (*onCollisionCallback)(const EntityId entityId1, const EntityId entityId2), bool affectsCollidingTransform);
void removeCollisionComponent(EntityId entityId);
EntityId getParent(EntityId child);
EntityId getAncestor(EntityId child);
void setParent(EntityId child, EntityId parent, bool preserveScaling);
bool addAnimationComponent(EntityId entity);
void removeAnimationComponent(EntityId entity);
/// @brief renders an outline around the specified entity.
///
///
void setStencilHighlight(EntityId entity, float r, float g, float b);
/// @brief removes the outline around the specified entity.
///
///
void removeStencilHighlight(EntityId entity);
/// @brief returns the number of instances of the FilamentAsset represented by the given entity.
/// @param entityId
/// @return the number of instances
int getInstanceCount(EntityId entityId);
/// @brief returns an array containing all instances of the FilamentAsset represented by the given entity.
/// @param entityId
void getInstances(EntityId entityId, EntityId *out);
///
/// Sets the draw priority for the given entity. See RenderableManager.h for more details.
///
void setPriority(EntityId entity, int priority);
/// @brief returns the 2D min/max viewport coordinates of the bounding box for the specified enitty;
/// @param out a pointer large enough to store four floats (the min/max coordinates of the bounding box)
/// @return
///
Aabb2 getScreenSpaceBoundingBox(View* view, EntityId entity);
/// @brief returns the 3D bounding box of the renderable instance for the given entity.
/// @return the bounding box
///
Aabb3 getRenderableBoundingBox(EntityId entity);
///
/// Creates an entity with the specified geometry/material/normals and adds to the scene.
/// If [keepData] is true, stores
///
EntityId createGeometry(
float *vertices,
uint32_t numVertices,
float *normals,
uint32_t numNormals,
float *uvs,
uint32_t numUvs,
uint16_t *indices,
uint32_t numIndices,
filament::RenderableManager::PrimitiveType primitiveType = RenderableManager::PrimitiveType::TRIANGLES,
MaterialInstance* materialInstance = nullptr,
bool keepData = false
);
friend class FilamentViewer;
gltfio::MaterialProvider * const unlitMaterialProvider() {
return _unlitMaterialProvider;
}
bool isGeometryInstance(EntityId entity) {
return std::find(_geometryInstances.begin(), _geometryInstances.end(), entity) != _geometryInstances.end();
}
bool isGeometryEntity(EntityId entity) {
return _geometry.find(entity) != _geometry.end();
}
CustomGeometry* const getGeometry(EntityId entityId) {
return _geometry[entityId].get();
}
bool isGltfAsset(EntityId entity) {
return getAssetByEntityId(entity) != nullptr;
}
gltfio::FilamentInstance *getInstanceByEntityId(EntityId entityId);
gltfio::FilamentAsset *getAssetByEntityId(EntityId entityId);
gltfio::FilamentInstance *createGltfAssetInstance(FilamentAsset* asset) {
return _assetLoader->createInstance(asset);
}
MaterialInstance* getMaterialInstanceAt(EntityId entityId, int materialIndex);
void setMaterialProperty(EntityId entity, int materialIndex, const char* property, float value);
void setMaterialProperty(EntityId entity, int materialIndex, const char* property, int32_t value);
void setMaterialProperty(EntityId entityId, int materialIndex, const char* property, filament::math::float4& value);
MaterialInstance* createUbershaderMaterialInstance(MaterialKey key);
void destroy(MaterialInstance* materialInstance);
gltfio::MaterialProvider* getUbershaderProvider() {
return _ubershaderProvider;
}
MaterialInstance* createUnlitFixedSizeMaterialInstance();
MaterialInstance* createUnlitMaterialInstance();
void setVisibilityLayer(EntityId entityId, int layer);
Camera* createCamera();
void destroyCamera(Camera* camera);
size_t getCameraCount();
Camera* getCameraAt(size_t index);
Gizmo *createGizmo(View *view, Scene *scene);
bool isGizmoEntity(utils::Entity entity);
Scene* getScene() {
return _scene;
}
private:
gltfio::AssetLoader *_assetLoader = nullptr;
const ResourceLoaderWrapperImpl *const _resourceLoaderWrapper;
Engine *_engine = nullptr;
Scene *_scene = nullptr;
Camera* _mainCamera;
gltfio::MaterialProvider *_ubershaderProvider = nullptr;
gltfio::MaterialProvider *_unlitMaterialProvider = nullptr;
gltfio::ResourceLoader *_gltfResourceLoader = nullptr;
gltfio::TextureProvider *_stbDecoder = nullptr;
gltfio::TextureProvider *_ktxDecoder = nullptr;
std::mutex _mutex;
std::mutex _stencilMutex;
std::vector<MaterialInstance*> _materialInstances;
Material* _gizmoMaterial = nullptr;
utils::NameComponentManager *_ncm;
tsl::robin_map<
EntityId,
gltfio::FilamentInstance *>
_instances;
tsl::robin_map<EntityId, gltfio::FilamentAsset *> _assets;
tsl::robin_map<EntityId, unique_ptr<CustomGeometry>> _geometry;
std::vector<EntityId> _geometryInstances;
tsl::robin_map<EntityId, unique_ptr<HighlightOverlay>> _highlighted;
tsl::robin_map<EntityId, math::mat4> _transformUpdates;
std::set<Texture*> _textures;
std::vector<Camera*> _cameras;
AnimationComponentManager *_animationComponentManager = nullptr;
CollisionComponentManager *_collisionComponentManager = nullptr;
utils::Entity findEntityByName(
const gltfio::FilamentInstance *instance,
const char *entityName);
GridOverlay* _gridOverlay = nullptr;
};
}

View File

@@ -1,18 +0,0 @@
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
#include "ThermionDartApi.h"
#include "TGizmo.h"
typedef void (*GizmoPickCallback)(EntityId entityId, uint32_t x, uint32_t y, TView* view);
EMSCRIPTEN_KEEPALIVE void Gizmo_pick(TGizmo *tGizmo, uint32_t x, uint32_t y, GizmoPickCallback callback);
EMSCRIPTEN_KEEPALIVE void Gizmo_setVisibility(TGizmo *tGizmo, bool visible);
#ifdef __cplusplus
}
#endif

View File

@@ -1,78 +0,0 @@
#pragma once
#ifdef _WIN32
#ifdef IS_DLL
#define EMSCRIPTEN_KEEPALIVE __declspec(dllimport)
#else
#define EMSCRIPTEN_KEEPALIVE __declspec(dllexport)
#endif
#else
#ifndef EMSCRIPTEN_KEEPALIVE
#define EMSCRIPTEN_KEEPALIVE __attribute__((visibility("default")))
#endif
#endif
// we copy the LLVM <stdbool.h> here rather than including,
// because on Windows it's difficult to pin the exact location which confuses dart ffigen
#ifndef __STDBOOL_H
#define __STDBOOL_H
#define __bool_true_false_are_defined 1
#if defined(__STDC_VERSION__) && __STDC_VERSION__ > 201710L
/* FIXME: We should be issuing a deprecation warning here, but cannot yet due
* to system headers which include this header file unconditionally.
*/
#elif !defined(__cplusplus)
#define bool _Bool
#define true 1
#define false 0
#elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
/* Define _Bool as a GNU extension. */
#define _Bool bool
#if defined(__cplusplus) && __cplusplus < 201103L
/* For C++98, define bool, false, true as a GNU extension. */
#define bool bool
#define false false
#define true true
#endif
#endif
#endif /* __STDBOOL_H */
#if defined(__APPLE__) || defined(__EMSCRIPTEN__)
#include <stddef.h>
#endif
typedef struct TMaterialInstance TMaterialInstance;
// copied from SamplerCompareFunc in DriverEnums.h
enum TDepthFunc {
// don't change the enums values
LE = 0, //!< Less or equal
GE, //!< Greater or equal
L, //!< Strictly less than
G, //!< Strictly greater than
E, //!< Equal
NE, //!< Not equal
A, //!< Always. Depth / stencil testing is deactivated.
N //!< Never. The depth / stencil test always fails.
};
#ifdef __cplusplus
extern "C"
{
#endif
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthWrite(TMaterialInstance* materialInstance, bool enabled);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthCulling(TMaterialInstance* materialInstance, bool enabled);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat4(TMaterialInstance* materialInstance, const char* name, double x, double y, double w, double z);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat2(TMaterialInstance* materialInstance, const char* name, double x, double y);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat(TMaterialInstance* materialInstance, const char* name, double value);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterInt(TMaterialInstance* materialInstance, const char* name, int value);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthFunc(TMaterialInstance* materialInstance, TDepthFunc depthFunc);
#ifdef __cplusplus
}
#endif

View File

@@ -1,54 +0,0 @@
#pragma once
#include "APIBoundaryTypes.h"
#include "ResourceBuffer.hpp"
#include "ThermionDartAPIUtils.h"
#include "TCamera.h"
#include "TMaterialInstance.h"
#ifdef __cplusplus
extern "C"
{
#endif
EMSCRIPTEN_KEEPALIVE TGizmo* SceneManager_createGizmo(TSceneManager *tSceneManager, TView *tView, TScene *tScene);
EMSCRIPTEN_KEEPALIVE EntityId SceneManager_createGeometry(
TSceneManager *sceneManager,
float *vertices,
int numVertices,
float *normals,
int numNormals,
float *uvs,
int numUvs,
uint16_t *indices,
int numIndices,
int primitiveType,
TMaterialInstance *materialInstance,
bool keepData);
EMSCRIPTEN_KEEPALIVE TMaterialInstance *SceneManager_createUnlitMaterialInstance(TSceneManager *sceneManager);
EMSCRIPTEN_KEEPALIVE TMaterialInstance *SceneManager_createUnlitFixedSizeMaterialInstance(TSceneManager *sceneManager);
EMSCRIPTEN_KEEPALIVE bool SceneManager_setTransform(TSceneManager *sceneManager, EntityId entityId, const double *const transform);
EMSCRIPTEN_KEEPALIVE void SceneManager_queueTransformUpdates(TSceneManager *sceneManager, EntityId* entities, const double* const transforms, int numEntities);
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, bool loadResourcesAsync);
EMSCRIPTEN_KEEPALIVE bool SceneManager_setMorphAnimation(
TSceneManager *sceneManager,
EntityId entity,
const float *const morphData,
const uint32_t *const morphIndices,
int numMorphTargets,
int numFrames,
float frameLengthInMs);
EMSCRIPTEN_KEEPALIVE TCamera* SceneManager_createCamera(TSceneManager *sceneManager);
EMSCRIPTEN_KEEPALIVE void SceneManager_destroyCamera(TSceneManager *sceneManager, TCamera* camera);
EMSCRIPTEN_KEEPALIVE size_t SceneManager_getCameraCount(TSceneManager *sceneManager);
EMSCRIPTEN_KEEPALIVE TCamera* SceneManager_getCameraAt(TSceneManager *sceneManager, size_t index);
EMSCRIPTEN_KEEPALIVE void SceneManager_destroyMaterialInstance(TSceneManager *sceneManager, TMaterialInstance *instance);
#ifdef __cplusplus
}
#endif

View File

@@ -1,216 +0,0 @@
#ifndef _FLUTTER_FILAMENT_API_H
#define _FLUTTER_FILAMENT_API_H
#include "APIExport.h"
#include "APIBoundaryTypes.h"
#include "ResourceBuffer.hpp"
#include "ThermionDartAPIUtils.h"
#include "TMaterialInstance.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 Viewer_destroy(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE TSceneManager *Viewer_getSceneManager(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE TRenderTarget* Viewer_createRenderTarget(TViewer *viewer, intptr_t texture, uint32_t width, uint32_t height);
EMSCRIPTEN_KEEPALIVE void Viewer_destroyRenderTarget(TViewer *viewer, TRenderTarget* tRenderTarget);
EMSCRIPTEN_KEEPALIVE TSwapChain *Viewer_createSwapChain(TViewer *viewer, const void *const window);
EMSCRIPTEN_KEEPALIVE TSwapChain *Viewer_createHeadlessSwapChain(TViewer *viewer, uint32_t width, uint32_t height);
EMSCRIPTEN_KEEPALIVE void Viewer_destroySwapChain(TViewer *viewer, TSwapChain* swapChain);
EMSCRIPTEN_KEEPALIVE void Viewer_render(
TViewer *viewer);
EMSCRIPTEN_KEEPALIVE void Viewer_capture(
TViewer *viewer,
TView *view,
TSwapChain *swapChain,
uint8_t *pixelBuffer,
void (*callback)(void));
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderTarget(
TViewer *viewer,
TView *view,
TSwapChain *swapChain,
TRenderTarget *renderTarget,
uint8_t *pixelBuffer,
void (*callback)(void));
EMSCRIPTEN_KEEPALIVE TView* Viewer_createView(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE TView* Viewer_getViewAt(TViewer *viewer, int index);
EMSCRIPTEN_KEEPALIVE void Viewer_setMainCamera(TViewer *tViewer, TView *tView);
EMSCRIPTEN_KEEPALIVE TSwapChain* Viewer_getSwapChainAt(TViewer *tViewer, int index);
EMSCRIPTEN_KEEPALIVE void Viewer_setViewRenderable(TViewer *viewer, TSwapChain *swapChain, TView* view, bool renderable);
EMSCRIPTEN_KEEPALIVE void Viewer_pick(TViewer *viewer, TView* tView, int x, int y, void (*callback)(EntityId entityId, int x, int y, TView *tView, float depth, float fragX, float fragY, float fragZ));
EMSCRIPTEN_KEEPALIVE bool Viewer_isNonPickableEntity(TViewer *viewer, EntityId entityId);
// Engine
EMSCRIPTEN_KEEPALIVE TEngine *Viewer_getEngine(TViewer* viewer);
EMSCRIPTEN_KEEPALIVE TCamera *Engine_getCameraComponent(TEngine* tEngine, EntityId entityId);
EMSCRIPTEN_KEEPALIVE void Engine_setTransform(TEngine* tEngine, EntityId entity, double4x4 transform);
EMSCRIPTEN_KEEPALIVE void clear_background_image(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE void set_background_image(TViewer *viewer, const char *path, bool fillHeight);
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 load_skybox(TViewer *viewer, const char *skyboxPath);
EMSCRIPTEN_KEEPALIVE void Viewer_loadIbl(TViewer *viewer, const char *iblPath, float intensity);
EMSCRIPTEN_KEEPALIVE void create_ibl(TViewer *viewer, float r, float g, float b, float intensity);
EMSCRIPTEN_KEEPALIVE void rotate_ibl(TViewer *viewer, float *rotationMatrix);
EMSCRIPTEN_KEEPALIVE void remove_skybox(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE void remove_ibl(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE EntityId add_light(
TViewer *viewer,
uint8_t type,
float colour,
float intensity,
float posX,
float posY,
float posZ,
float dirX,
float dirY,
float dirZ,
float falloffRadius,
float spotLightConeInner,
float spotLightConeOuter,
float sunAngularRadius,
float sunHaloSize,
float sunHaloFallof,
bool shadows);
EMSCRIPTEN_KEEPALIVE void remove_light(TViewer *viewer, EntityId entityId);
EMSCRIPTEN_KEEPALIVE void clear_lights(TViewer *viewer);
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_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_frame_interval(TViewer *viewer, float interval);
EMSCRIPTEN_KEEPALIVE void apply_weights(
TSceneManager *sceneManager,
EntityId entity,
const char *const entityName,
float *const weights,
int count);
EMSCRIPTEN_KEEPALIVE bool set_morph_target_weights(
TSceneManager *sceneManager,
EntityId entity,
const float *const morphData,
int numWeights);
EMSCRIPTEN_KEEPALIVE TMaterialInstance *create_material_instance(TSceneManager *sceneManager, TMaterialKey materialConfig);
EMSCRIPTEN_KEEPALIVE void clear_morph_animation(
TSceneManager *sceneManager,
EntityId entity);
EMSCRIPTEN_KEEPALIVE void reset_to_rest_pose(
TSceneManager *sceneManager,
EntityId asset);
EMSCRIPTEN_KEEPALIVE void add_bone_animation(
TSceneManager *sceneManager,
EntityId entity,
int skinIndex,
int boneIndex,
const float *const frameData,
int numFrames,
float frameLengthInMs,
float fadeOutInSecs,
float fadeInInSecs,
float maxDelta);
EMSCRIPTEN_KEEPALIVE void get_local_transform(TSceneManager *sceneManager,
EntityId entityId, float *const);
EMSCRIPTEN_KEEPALIVE void get_rest_local_transforms(TSceneManager *sceneManager,
EntityId entityId, int skinIndex, float *const out, int numBones);
EMSCRIPTEN_KEEPALIVE void get_world_transform(TSceneManager *sceneManager,
EntityId entityId, float *const);
EMSCRIPTEN_KEEPALIVE void get_inverse_bind_matrix(TSceneManager *sceneManager,
EntityId entityId, int skinIndex, int boneIndex, float *const);
EMSCRIPTEN_KEEPALIVE bool set_bone_transform(
TSceneManager *sceneManager,
EntityId entity,
int skinIndex,
int boneIndex,
const float *const transform);
EMSCRIPTEN_KEEPALIVE void play_animation(TSceneManager *sceneManager, EntityId entity, int index, bool loop, bool reverse, bool replaceActive, float crossfade, float startOffset);
EMSCRIPTEN_KEEPALIVE void set_animation_frame(TSceneManager *sceneManager, EntityId entity, int animationIndex, int animationFrame);
EMSCRIPTEN_KEEPALIVE void stop_animation(TSceneManager *sceneManager, EntityId entity, int index);
EMSCRIPTEN_KEEPALIVE int get_animation_count(TSceneManager *sceneManager, EntityId asset);
EMSCRIPTEN_KEEPALIVE void get_animation_name(TSceneManager *sceneManager, EntityId entity, char *const outPtr, int index);
EMSCRIPTEN_KEEPALIVE float get_animation_duration(TSceneManager *sceneManager, EntityId entity, int index);
EMSCRIPTEN_KEEPALIVE int get_bone_count(TSceneManager *sceneManager, EntityId assetEntity, int skinIndex);
EMSCRIPTEN_KEEPALIVE void get_bone_names(TSceneManager *sceneManager, EntityId assetEntity, const char **outPtr, int skinIndex);
EMSCRIPTEN_KEEPALIVE EntityId get_bone(TSceneManager *sceneManager,
EntityId entityId,
int skinIndex,
int boneIndex);
EMSCRIPTEN_KEEPALIVE bool update_bone_matrices(TSceneManager *sceneManager, EntityId entityId);
EMSCRIPTEN_KEEPALIVE void get_morph_target_name(TSceneManager *sceneManager, EntityId assetEntity, EntityId childEntity, char *const outPtr, int index);
EMSCRIPTEN_KEEPALIVE int get_morph_target_name_count(TSceneManager *sceneManager, EntityId assetEntity, EntityId childEntity);
EMSCRIPTEN_KEEPALIVE void remove_entity(TViewer *viewer, EntityId asset);
EMSCRIPTEN_KEEPALIVE void clear_entities(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE bool set_material_color(TSceneManager *sceneManager, EntityId entity, const char *meshName, int materialIndex, const float r, const float g, const float b, const float a);
EMSCRIPTEN_KEEPALIVE void transform_to_unit_cube(TSceneManager *sceneManager, EntityId asset);
EMSCRIPTEN_KEEPALIVE void queue_relative_position_update_world_axis(TSceneManager *sceneManager, EntityId entity, float viewportX, float viewportY, float x, float y, float z);
EMSCRIPTEN_KEEPALIVE void queue_position_update_from_viewport_coords(TSceneManager *sceneManager, TView *view, EntityId entity, float viewportX, float viewportY);
EMSCRIPTEN_KEEPALIVE void set_position(TSceneManager *sceneManager, EntityId entity, float x, float y, float z);
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);
EMSCRIPTEN_KEEPALIVE TCamera *Engine_getCameraComponent(TEngine *engine, EntityId entity);
EMSCRIPTEN_KEEPALIVE TEntityManager *Engine_getEntityManager(TEngine *engine);
EMSCRIPTEN_KEEPALIVE int hide_mesh(TSceneManager *sceneManager, EntityId entity, const char *meshName);
EMSCRIPTEN_KEEPALIVE int reveal_mesh(TSceneManager *sceneManager, EntityId entity, const char *meshName);
EMSCRIPTEN_KEEPALIVE const char *get_name_for_entity(TSceneManager *sceneManager, const EntityId entityId);
EMSCRIPTEN_KEEPALIVE EntityId find_child_entity_by_name(TSceneManager *sceneManager, const EntityId parent, const char *name);
EMSCRIPTEN_KEEPALIVE int get_entity_count(TSceneManager *sceneManager, const EntityId target, bool renderableOnly);
EMSCRIPTEN_KEEPALIVE void get_entities(TSceneManager *sceneManager, const EntityId target, bool renderableOnly, EntityId *out);
EMSCRIPTEN_KEEPALIVE const char *get_entity_name_at(TSceneManager *sceneManager, const EntityId target, int index, bool renderableOnly);
EMSCRIPTEN_KEEPALIVE void ios_dummy();
EMSCRIPTEN_KEEPALIVE void thermion_flutter_free(void *ptr);
EMSCRIPTEN_KEEPALIVE void add_collision_component(TSceneManager *sceneManager, EntityId entityId, void (*callback)(const EntityId entityId1, const EntityId entityId2), bool affectsCollidingTransform);
EMSCRIPTEN_KEEPALIVE void remove_collision_component(TSceneManager *sceneManager, EntityId entityId);
EMSCRIPTEN_KEEPALIVE bool add_animation_component(TSceneManager *sceneManager, EntityId entityId);
EMSCRIPTEN_KEEPALIVE void remove_animation_component(TSceneManager *sceneManager, EntityId entityId);
EMSCRIPTEN_KEEPALIVE EntityId get_parent(TSceneManager *sceneManager, EntityId child);
EMSCRIPTEN_KEEPALIVE EntityId get_ancestor(TSceneManager *sceneManager, EntityId child);
EMSCRIPTEN_KEEPALIVE void set_parent(TSceneManager *sceneManager, EntityId child, EntityId parent, bool preserveScaling);
EMSCRIPTEN_KEEPALIVE void test_collisions(TSceneManager *sceneManager, EntityId entity);
EMSCRIPTEN_KEEPALIVE void set_priority(TSceneManager *sceneManager, EntityId entityId, int priority);
EMSCRIPTEN_KEEPALIVE Aabb2 get_bounding_box(TSceneManager *sceneManager, TView *view, EntityId entity);
EMSCRIPTEN_KEEPALIVE void get_bounding_box_to_out(TSceneManager *sceneManager, TView *view, EntityId entity, float *minX, float *minY, float *maxX, float *maxY);
EMSCRIPTEN_KEEPALIVE void set_stencil_highlight(TSceneManager *sceneManager, EntityId entity, float r, float g, float b);
EMSCRIPTEN_KEEPALIVE void remove_stencil_highlight(TSceneManager *sceneManager, EntityId entity);
EMSCRIPTEN_KEEPALIVE void set_material_property_float(TSceneManager *sceneManager, EntityId entity, int materialIndex, const char *property, float value);
EMSCRIPTEN_KEEPALIVE void set_material_property_int(TSceneManager *sceneManager, EntityId entity, int materialIndex, const char *property, int value);
EMSCRIPTEN_KEEPALIVE void set_material_property_float4(TSceneManager *sceneManager, EntityId entity, int materialIndex, const char *property, double4 value);
EMSCRIPTEN_KEEPALIVE void set_material_depth_write(TSceneManager *sceneManager, EntityId entity, int materialIndex, bool enabled);
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 *const create_texture(TSceneManager *sceneManager, uint8_t *data, size_t length);
EMSCRIPTEN_KEEPALIVE void destroy_texture(TSceneManager *sceneManager, void *const texture);
EMSCRIPTEN_KEEPALIVE void apply_texture_to_material(TSceneManager *sceneManager, EntityId entity, void *const texture, const char *parameterName, int materialIndex);
EMSCRIPTEN_KEEPALIVE TMaterialInstance* get_material_instance_at(TSceneManager *sceneManager, EntityId entity, int materialIndex);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,116 +0,0 @@
#ifndef _DART_FILAMENT_FFI_API_H
#define _DART_FILAMENT_FFI_API_H
#include "ThermionDartApi.h"
#include "TView.h"
#ifdef __cplusplus
namespace thermion {
extern "C"
{
#endif
///
/// This header replicates most of the methods in ThermionDartApi.h.
/// It represents the interface for:
/// - invoking those methods that must be called on the main Filament engine thread
/// - setting up a render loop
///
typedef int32_t EntityId;
typedef void (*FilamentRenderCallback)(void *const owner);
EMSCRIPTEN_KEEPALIVE void Viewer_createOnRenderThread(
void *const context,
void *const platform,
const char *uberArchivePath,
const void *const loader,
void (*renderCallback)(void *const renderCallbackOwner),
void *const renderCallbackOwner,
void (*callback)(TViewer *viewer));
EMSCRIPTEN_KEEPALIVE void Viewer_destroyOnRenderThread(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE void Viewer_createSwapChainRenderThread(TViewer *viewer, void *const surface, void (*onComplete)(TSwapChain*));
EMSCRIPTEN_KEEPALIVE void Viewer_createHeadlessSwapChainRenderThread(TViewer *viewer, uint32_t width, uint32_t height, void (*onComplete)(TSwapChain*));
EMSCRIPTEN_KEEPALIVE void Viewer_destroySwapChainRenderThread(TViewer *viewer, TSwapChain* swapChain, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Viewer_renderRenderThread(TViewer *viewer, TView* view, TSwapChain* swapChain);
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderThread(TViewer *viewer, TView* view, TSwapChain* swapChain, uint8_t* out, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderTargetRenderThread(TViewer *viewer, TView* view, TSwapChain* swapChain, TRenderTarget* renderTarget, uint8_t* out, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Viewer_requestFrameRenderThread(TViewer *viewer, void(*onComplete)());
EMSCRIPTEN_KEEPALIVE void Viewer_loadIblRenderThread(TViewer *viewer, const char *iblPath, float intensity, void(*onComplete)());
EMSCRIPTEN_KEEPALIVE void Viewer_createRenderTargetRenderThread(TViewer *viewer, intptr_t texture, uint32_t width, uint32_t height, void(*onComplete)(TRenderTarget*));
EMSCRIPTEN_KEEPALIVE void View_setToneMappingRenderThread(TView *tView, TEngine *tEngine, thermion::ToneMapping toneMapping);
EMSCRIPTEN_KEEPALIVE void View_setBloomRenderThread(TView *tView, double bloom);
FilamentRenderCallback make_render_callback_fn_pointer(FilamentRenderCallback);
EMSCRIPTEN_KEEPALIVE void set_rendering_render_thread(TViewer *viewer, bool rendering, void(*onComplete)());
EMSCRIPTEN_KEEPALIVE void set_frame_interval_render_thread(TViewer *viewer, float frameInterval);
EMSCRIPTEN_KEEPALIVE void set_background_color_render_thread(TViewer *viewer, const float r, const float g, const float b, const float a);
EMSCRIPTEN_KEEPALIVE void clear_background_image_render_thread(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE void set_background_image_render_thread(TViewer *viewer, const char *path, bool fillHeight, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void set_background_image_position_render_thread(TViewer *viewer, float x, float y, bool clamp);
EMSCRIPTEN_KEEPALIVE void load_skybox_render_thread(TViewer *viewer, const char *skyboxPath, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void remove_skybox_render_thread(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE void SceneManager_createGeometryRenderThread(
TSceneManager *sceneManager,
float *vertices,
int numVertices,
float *normals,
int numNormals,
float *uvs,
int numUvs,
uint16_t *indices,
int numIndices,
int primitiveType,
TMaterialInstance *materialInstance,
bool keepData,
void (*callback)(EntityId));
EMSCRIPTEN_KEEPALIVE void SceneManager_loadGlbFromBufferRenderThread(TSceneManager *sceneManager, const uint8_t *const data, size_t length, int numInstances, bool keepData, int priority, int layer, bool loadResourcesAsync, void (*callback)(EntityId));
EMSCRIPTEN_KEEPALIVE void SceneManager_createUnlitMaterialInstanceRenderThread(TSceneManager *sceneManager, void (*callback)(TMaterialInstance*));
EMSCRIPTEN_KEEPALIVE void SceneManager_createUnlitFixedSizeMaterialInstanceRenderThread(TSceneManager *sceneManager, void (*callback)(TMaterialInstance*));
EMSCRIPTEN_KEEPALIVE void load_glb_render_thread(TSceneManager *sceneManager, const char *assetPath, int numInstances, bool keepData, void (*callback)(EntityId));
EMSCRIPTEN_KEEPALIVE void load_gltf_render_thread(TSceneManager *sceneManager, const char *assetPath, const char *relativePath, bool keepData, void (*callback)(EntityId));
EMSCRIPTEN_KEEPALIVE void create_instance_render_thread(TSceneManager *sceneManager, EntityId entityId, void (*callback)(EntityId));
EMSCRIPTEN_KEEPALIVE void remove_entity_render_thread(TViewer *viewer, EntityId asset, void (*callback)());
EMSCRIPTEN_KEEPALIVE void clear_entities_render_thread(TViewer *viewer, void (*callback)());
EMSCRIPTEN_KEEPALIVE void apply_weights_render_thread(
TSceneManager *sceneManager,
EntityId asset,
const char *const entityName,
float *const weights,
int count);
EMSCRIPTEN_KEEPALIVE void set_animation_frame_render_thread(TSceneManager *sceneManager, EntityId asset, int animationIndex, int animationFrame);
EMSCRIPTEN_KEEPALIVE void stop_animation_render_thread(TSceneManager *sceneManager, EntityId asset, int index);
EMSCRIPTEN_KEEPALIVE void get_animation_count_render_thread(TSceneManager *sceneManager, EntityId asset, void (*callback)(int));
EMSCRIPTEN_KEEPALIVE void get_animation_name_render_thread(TSceneManager *sceneManager, EntityId asset, char *const outPtr, int index, void (*callback)());
EMSCRIPTEN_KEEPALIVE void get_morph_target_name_render_thread(TSceneManager *sceneManager, EntityId assetEntity, EntityId childEntity, char *const outPtr, int index, void (*callback)());
EMSCRIPTEN_KEEPALIVE void get_morph_target_name_count_render_thread(TSceneManager *sceneManager, EntityId asset, EntityId childEntity, void (*callback)(int32_t));
EMSCRIPTEN_KEEPALIVE void set_morph_target_weights_render_thread(TSceneManager *sceneManager,
EntityId asset,
const float *const morphData,
int numWeights,
void (*callback)(bool));
EMSCRIPTEN_KEEPALIVE void update_bone_matrices_render_thread(TSceneManager *sceneManager,
EntityId asset, void(*callback)(bool));
EMSCRIPTEN_KEEPALIVE void set_bone_transform_render_thread(
TSceneManager *sceneManager,
EntityId asset,
int skinIndex,
int boneIndex,
const float *const transform,
void (*callback)(bool));
EMSCRIPTEN_KEEPALIVE void set_post_processing_render_thread(TViewer *viewer, bool enabled);
EMSCRIPTEN_KEEPALIVE void reset_to_rest_pose_render_thread(TSceneManager *sceneManager, EntityId entityId, void(*callback)());
EMSCRIPTEN_KEEPALIVE void unproject_texture_render_thread(TViewer* viewer, EntityId entity, uint8_t* input, uint32_t inputWidth, uint32_t inputHeight, uint8_t* out, uint32_t outWidth, uint32_t outHeight, void(*callback)());
#ifdef __cplusplus
}
}
#endif
#endif // _DART_FILAMENT_FFI_API_H

View File

@@ -15,7 +15,7 @@
#include <vector>
#include <algorithm>
#include "CustomGeometry.hpp"
#include "scene/CustomGeometry.hpp"
namespace thermion {

View File

@@ -6,7 +6,6 @@ extern "C"
#endif
#include <stdint.h>
#include "TMaterialInstance.h"
typedef int32_t EntityId;
typedef struct TCamera TCamera;
@@ -19,6 +18,15 @@ extern "C"
typedef struct TView TView;
typedef struct TGizmo TGizmo;
typedef struct TScene TScene;
typedef struct TTransformManager TTransformManager;
typedef struct TAnimationManager TAnimationManager;
typedef struct TCollisionComponentManager TCollisionComponentManager;
typedef struct TSceneAsset TSceneAsset;
typedef struct TNameComponentManager TNameComponentManager;
typedef struct TMaterialInstance TMaterialInstance;
typedef struct TMaterialProvider TMaterialProvider;
typedef struct TRenderableManager TRenderableManager;
typedef struct TRenderableInstance TRenderableInstance;
struct TMaterialKey {
bool doubleSided;

View File

@@ -0,0 +1,136 @@
#pragma once
#include "APIExport.h"
#include "APIBoundaryTypes.h"
#ifdef __cplusplus
extern "C"
{
#endif
EMSCRIPTEN_KEEPALIVE void AnimationManager_addAnimationComponent(TAnimationManager *tAnimationManager, EntityId entityId);
EMSCRIPTEN_KEEPALIVE void AnimationManager_removeAnimationComponent(TAnimationManager *tAnimationManager, EntityId entityId);
EMSCRIPTEN_KEEPALIVE bool AnimationManager_setMorphAnimation(
TAnimationManager *tAnimationManager,
EntityId entityId,
const float *const morphData,
const uint32_t *const morphIndices,
int numMorphTargets,
int numFrames,
float frameLengthInMs);
EMSCRIPTEN_KEEPALIVE bool AnimationManager_clearMorphAnimation(TAnimationManager *tAnimationManager, EntityId entityId);
EMSCRIPTEN_KEEPALIVE void AnimationManager_resetToRestPose(TAnimationManager *tAnimationManager, TSceneAsset *sceneAsset);
EMSCRIPTEN_KEEPALIVE void AnimationManager_addBoneAnimation(
TAnimationManager *tAnimationManager,
TSceneAsset *tSceneAsset,
int skinIndex,
int boneIndex,
const float *const frameData,
int numFrames,
float frameLengthInMs,
float fadeOutInSecs,
float fadeInInSecs,
float maxDelta);
EMSCRIPTEN_KEEPALIVE EntityId AnimationManager_getBone(
TAnimationManager *tAnimationManager,
TSceneAsset *sceneAsset,
int skinIndex,
int boneIndex);
EMSCRIPTEN_KEEPALIVE void AnimationManager_getRestLocalTransforms(
TAnimationManager *tAnimationManager,
TSceneAsset *sceneAsset,
int skinIndex,
float *const out,
int numBones);
EMSCRIPTEN_KEEPALIVE void AnimationManager_getInverseBindMatrix(
TAnimationManager *tAnimationManager,
TSceneAsset *sceneAsset,
int skinIndex,
int boneIndex,
float *const out);
EMSCRIPTEN_KEEPALIVE void AnimationManager_playAnimation(
TAnimationManager *tAnimationManager,
TSceneAsset *sceneAsset,
int index,
bool loop,
bool reverse,
bool replaceActive,
float crossfade,
float startOffset);
EMSCRIPTEN_KEEPALIVE void AnimationManager_stopAnimation(
TAnimationManager *tAnimationManager,
TSceneAsset *sceneAsset,
int index);
// Additional methods found in implementation
EMSCRIPTEN_KEEPALIVE float AnimationManager_getAnimationDuration(
TAnimationManager *tAnimationManager,
TSceneAsset *sceneAsset,
int animationIndex);
EMSCRIPTEN_KEEPALIVE int AnimationManager_getAnimationCount(
TAnimationManager *tAnimationManager,
TSceneAsset *sceneAsset);
EMSCRIPTEN_KEEPALIVE void AnimationManager_getAnimationName(
TAnimationManager *tAnimationManager,
TSceneAsset *sceneAsset,
char *const outPtr,
int index);
EMSCRIPTEN_KEEPALIVE int AnimationManager_getBoneCount(
TAnimationManager *tAnimationManager,
TSceneAsset *sceneAsset,
int skinIndex);
EMSCRIPTEN_KEEPALIVE void AnimationManager_getBoneNames(
TAnimationManager *tAnimationManager,
TSceneAsset *sceneAsset,
const char **out,
int skinIndex);
EMSCRIPTEN_KEEPALIVE int AnimationManager_getMorphTargetNameCount(
TAnimationManager *tAnimationManager,
TSceneAsset *sceneAsset,
EntityId childEntity);
EMSCRIPTEN_KEEPALIVE void AnimationManager_getMorphTargetName(
TAnimationManager *tAnimationManager,
TSceneAsset *sceneAsset,
EntityId childEntity,
char *const outPtr,
int index);
EMSCRIPTEN_KEEPALIVE bool AnimationManager_updateBoneMatrices(
TAnimationManager *tAnimationManager,
TSceneAsset *sceneAsset);
EMSCRIPTEN_KEEPALIVE bool AnimationManager_setMorphTargetWeights(
TAnimationManager *tAnimationManager,
EntityId entityId,
const float *const morphData,
int numWeights);
EMSCRIPTEN_KEEPALIVE void AnimationManager_setGltfAnimationFrame(
TAnimationManager *tAnimationManager,
TSceneAsset *tSceneAsset,
int animationIndex,
int frame
);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,25 @@
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
#include <stddef.h>
#include "APIBoundaryTypes.h"
#include "APIExport.h"
#include "TView.h"
enum TGizmoAxis { X, Y, Z };
enum TGizmoPickResultType { AxisX, AxisY, AxisZ, Parent, None };
typedef void (*GizmoPickCallback)(TGizmoPickResultType resultType, float x, float y, float z);
EMSCRIPTEN_KEEPALIVE void Gizmo_pick(TGizmo *tGizmo, uint32_t x, uint32_t y, GizmoPickCallback callback);
EMSCRIPTEN_KEEPALIVE void Gizmo_highlight(TGizmo *tGizmo, TGizmoAxis axis);
EMSCRIPTEN_KEEPALIVE void Gizmo_unhighlight(TGizmo *tGizmo);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,103 @@
#pragma once
#include "APIBoundaryTypes.h"
#include "APIExport.h"
#ifdef __cplusplus
extern "C"
{
#endif
// copied from SamplerCompareFunc in DriverEnums.h
enum TSamplerCompareFunc
{
// don't change the enums values
LE = 0, //!< Less or equal
GE, //!< Greater or equal
L, //!< Strictly less than
G, //!< Strictly greater than
E, //!< Equal
NE, //!< Not equal
A, //!< Always. Depth / stencil testing is deactivated.
N //!< Never. The depth / stencil test always fails.
};
// StencilOperation equivalent
enum TStencilOperation
{
KEEP = 0, // Keep the current value
ZERO, // Set the value to zero
REPLACE, // Set the value to reference value
INCR, // Increment the current value with saturation
INCR_WRAP, // Increment the current value without saturation
DECR, // Decrement the current value with saturation
DECR_WRAP, // Decrement the current value without saturation
INVERT // Invert the current value
};
// StencilFace equivalent
enum TStencilFace
{
STENCIL_FACE_FRONT = 1,
STENCIL_FACE_BACK = 2,
STENCIL_FACE_FRONT_AND_BACK = 3
};
// Add these enum definitions at the top with the other enums
enum TCullingMode
{
CULLING_MODE_NONE = 0,
CULLING_MODE_FRONT,
CULLING_MODE_BACK,
CULLING_MODE_FRONT_AND_BACK
};
EMSCRIPTEN_KEEPALIVE bool MaterialInstance_isStencilWriteEnabled(TMaterialInstance *materialInstance);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setStencilWrite(TMaterialInstance *materialInstance, bool enabled);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setCullingMode(TMaterialInstance *materialInstance, TCullingMode culling);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthWrite(TMaterialInstance *materialInstance, bool enabled);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthCulling(TMaterialInstance *materialInstance, bool enabled);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat4(TMaterialInstance *materialInstance, const char *name, double x, double y, double w, double z);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat2(TMaterialInstance *materialInstance, const char *name, double x, double y);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterFloat(TMaterialInstance *materialInstance, const char *name, double value);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setParameterInt(TMaterialInstance *materialInstance, const char *name, int value);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setDepthFunc(TMaterialInstance *materialInstance, TSamplerCompareFunc depthFunc);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setStencilOpStencilFail(
TMaterialInstance *materialInstance,
TStencilOperation op,
TStencilFace face);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setStencilOpDepthFail(
TMaterialInstance *materialInstance,
TStencilOperation op,
TStencilFace face);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setStencilOpDepthStencilPass(
TMaterialInstance *materialInstance,
TStencilOperation op,
TStencilFace face);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setStencilCompareFunction(
TMaterialInstance *materialInstance,
TSamplerCompareFunc func,
TStencilFace face);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setStencilReferenceValue(
TMaterialInstance *materialInstance,
uint8_t value,
TStencilFace face);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setStencilReadMask(
TMaterialInstance *materialInstance,
uint8_t mask);
EMSCRIPTEN_KEEPALIVE void MaterialInstance_setStencilWriteMask(
TMaterialInstance *materialInstance,
uint8_t mask);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,14 @@
#pragma once
#include "APIBoundaryTypes.h"
#include "APIExport.h"
#ifdef __cplusplus
extern "C"
{
#endif
EMSCRIPTEN_KEEPALIVE TMaterialInstance *MaterialProvider_createMaterialInstance(TMaterialProvider *provider, TMaterialKey *key);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,16 @@
#pragma once
#include "APIBoundaryTypes.h"
#include "APIExport.h"
#ifdef __cplusplus
extern "C"
{
#endif
EMSCRIPTEN_KEEPALIVE const char *NameComponentManager_getName(TNameComponentManager *tNameComponentManager, EntityId entity);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,17 @@
#pragma once
#include "APIExport.h"
#include "APIBoundaryTypes.h"
#ifdef __cplusplus
extern "C"
{
#endif
EMSCRIPTEN_KEEPALIVE void RenderableManager_setMaterialInstanceAt(TRenderableManager *tRenderableManager, EntityId entityId, int primitiveIndex, TMaterialInstance *tMaterialInstance);
EMSCRIPTEN_KEEPALIVE void RenderableManager_setPriority(TRenderableManager *tRenderableManager, EntityId entityId, int priority);
EMSCRIPTEN_KEEPALIVE TMaterialInstance *RenderableManager_getMaterialInstanceAt(TRenderableManager *tRenderableManager, EntityId entityId, int primitiveIndex);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,27 @@
#pragma once
#include <utils/Entity.h>
#include "APIExport.h"
#include "APIBoundaryTypes.h"
#ifdef __cplusplus
extern "C"
{
#endif
EMSCRIPTEN_KEEPALIVE void SceneAsset_addToScene(TSceneAsset *tSceneAsset, TScene *tScene);
EMSCRIPTEN_KEEPALIVE EntityId SceneAsset_getEntity(TSceneAsset *tSceneAsset);
EMSCRIPTEN_KEEPALIVE int SceneAsset_getChildEntityCount(TSceneAsset* tSceneAsset);
EMSCRIPTEN_KEEPALIVE void SceneAsset_getChildEntities(TSceneAsset* tSceneAsset, EntityId *out);
EMSCRIPTEN_KEEPALIVE const utils::Entity *SceneAsset_getCameraEntities(TSceneAsset* tSceneAsset);
EMSCRIPTEN_KEEPALIVE size_t SceneAsset_getCameraEntityCount(TSceneAsset *tSceneAsset);
EMSCRIPTEN_KEEPALIVE const utils::Entity *SceneAsset_getLightEntities(TSceneAsset* tSceneAsset);
EMSCRIPTEN_KEEPALIVE size_t SceneAsset_getLightEntityCount(TSceneAsset *tSceneAsset);
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneAsset_getInstance(TSceneAsset *tSceneAsset, int index);
EMSCRIPTEN_KEEPALIVE size_t SceneAsset_getInstanceCount(TSceneAsset *tSceneAsset);
EMSCRIPTEN_KEEPALIVE TSceneAsset * SceneAsset_createInstance(TSceneAsset *asset, TMaterialInstance **materialInstances, int materialInstanceCount);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,66 @@
#pragma once
#include "APIBoundaryTypes.h"
#include "ResourceBuffer.hpp"
#include "MathUtils.hpp"
#include "TCamera.h"
#include "TMaterialInstance.h"
#ifdef __cplusplus
extern "C"
{
#endif
EMSCRIPTEN_KEEPALIVE TGizmo *SceneManager_createGizmo(TSceneManager *tSceneManager, TView *tView, TScene *tScene);
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneManager_createGeometry(
TSceneManager *sceneManager,
float *vertices,
int numVertices,
float *normals,
int numNormals,
float *uvs,
int numUvs,
uint16_t *indices,
int numIndices,
int primitiveType,
TMaterialInstance **materialInstances,
int materialInstanceCount,
bool keepData);
EMSCRIPTEN_KEEPALIVE TMaterialProvider *SceneManager_getUbershaderMaterialProvider(TSceneManager *sceneManager);
EMSCRIPTEN_KEEPALIVE TMaterialProvider *SceneManager_getUnlitMaterialProvider(TSceneManager *sceneManager);
EMSCRIPTEN_KEEPALIVE TMaterialInstance *SceneManager_createUnlitMaterialInstance(TSceneManager *sceneManager);
EMSCRIPTEN_KEEPALIVE TMaterialInstance *SceneManager_createUnlitFixedSizeMaterialInstance(TSceneManager *sceneManager);
EMSCRIPTEN_KEEPALIVE void SceneManager_queueTransformUpdates(TSceneManager *sceneManager, EntityId *entities, const double *const transforms, int numEntities);
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 TCamera *SceneManager_createCamera(TSceneManager *sceneManager);
EMSCRIPTEN_KEEPALIVE void SceneManager_destroyCamera(TSceneManager *sceneManager, TCamera *camera);
EMSCRIPTEN_KEEPALIVE size_t SceneManager_getCameraCount(TSceneManager *sceneManager);
EMSCRIPTEN_KEEPALIVE TCamera *SceneManager_getCameraAt(TSceneManager *sceneManager, size_t index);
EMSCRIPTEN_KEEPALIVE void SceneManager_destroyMaterialInstance(TSceneManager *sceneManager, TMaterialInstance *instance);
EMSCRIPTEN_KEEPALIVE Aabb3 SceneManager_getRenderableBoundingBox(TSceneManager *tSceneManager, EntityId entity);
EMSCRIPTEN_KEEPALIVE int SceneManager_addToScene(TSceneManager *tSceneManager, EntityId entity);
EMSCRIPTEN_KEEPALIVE int SceneManager_removeFromScene(TSceneManager *tSceneManager, EntityId entity);
EMSCRIPTEN_KEEPALIVE void SceneManager_transformToUnitCube(TSceneManager *sceneManager, EntityId asset);
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneManager_loadGlbFromBuffer(TSceneManager *tSceneManager, const uint8_t *const, size_t length, bool keepData, int priority, int layer, bool loadResourcesAsync);
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneManager_loadGlb(TSceneManager *sceneManager, const char *assetPath, int numInstances, bool keepData);
EMSCRIPTEN_KEEPALIVE TSceneAsset *SceneManager_loadGltf(TSceneManager *sceneManager, const char *assetPath, const char *relativePath, bool keepData);
EMSCRIPTEN_KEEPALIVE TAnimationManager *SceneManager_getAnimationManager(TSceneManager *tSceneManager);
EMSCRIPTEN_KEEPALIVE void *SceneManager_destroyAll(TSceneManager *tSceneManager);
EMSCRIPTEN_KEEPALIVE void *SceneManager_destroyAsset(TSceneManager *tSceneManager, TSceneAsset *sceneAsset);
EMSCRIPTEN_KEEPALIVE TNameComponentManager *SceneManager_getNameComponentManager(TSceneManager *tSceneManager);
EMSCRIPTEN_KEEPALIVE size_t SceneManager_getOverlayEntityCount(TSceneManager *tSceneManager);
EMSCRIPTEN_KEEPALIVE EntityId SceneManager_getOverlayEntityAt(TSceneManager *tSceneManager, size_t index);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,23 @@
#pragma once
#include "APIExport.h"
#include "APIBoundaryTypes.h"
#ifdef __cplusplus
extern "C"
{
#endif
EMSCRIPTEN_KEEPALIVE double4x4 TransformManager_getLocalTransform(TTransformManager *tTransformManager, EntityId entityId);
EMSCRIPTEN_KEEPALIVE double4x4 TransformManager_getWorldTransform(TTransformManager *tTransformManager, EntityId entityId);
EMSCRIPTEN_KEEPALIVE void TransformManager_setTransform(TTransformManager *tTransformManager, EntityId entityId, double4x4 transform);
EMSCRIPTEN_KEEPALIVE void TransformManager_transformToUnitCube(TTransformManager *tTransformManager, EntityId entityId);
EMSCRIPTEN_KEEPALIVE void TransformManager_setParent(TTransformManager *tTransformManager, EntityId child, EntityId parent, bool preserveScaling);
EMSCRIPTEN_KEEPALIVE EntityId TransformManager_getParent(TTransformManager *tTransformManager, EntityId child);
EMSCRIPTEN_KEEPALIVE EntityId TransformManager_getAncestor(TTransformManager *tTransformManager, EntityId childEntityId);
#ifdef __cplusplus
}
#endif

View File

@@ -6,7 +6,8 @@ extern "C"
{
#endif
#include "ThermionDartApi.h"
#include "APIBoundaryTypes.h"
#include "APIExport.h"
struct TViewport {
int32_t left;
@@ -42,6 +43,11 @@ EMSCRIPTEN_KEEPALIVE void View_setLayerEnabled(TView *tView, int layer, bool vis
EMSCRIPTEN_KEEPALIVE void View_setCamera(TView *tView, TCamera *tCamera);
EMSCRIPTEN_KEEPALIVE TScene* View_getScene(TView *tView);
EMSCRIPTEN_KEEPALIVE TCamera* View_getCamera(TView *tView);
EMSCRIPTEN_KEEPALIVE void View_setStencilBufferEnabled(TView *tView, bool enabled);
EMSCRIPTEN_KEEPALIVE bool View_isStencilBufferEnabled(TView *tView);
typedef void (*PickCallback)(uint32_t requestId, EntityId entityId, float depth, float fragX, float fragY, float fragZ);
EMSCRIPTEN_KEEPALIVE void View_pick(TView* tView, uint32_t requestId, uint32_t x, uint32_t y, PickCallback callback);
#ifdef __cplusplus
}

View File

@@ -0,0 +1,115 @@
#ifndef _FLUTTER_FILAMENT_API_H
#define _FLUTTER_FILAMENT_API_H
#include "APIExport.h"
#include "APIBoundaryTypes.h"
#include "TMaterialInstance.h"
#include "ResourceBuffer.hpp"
#include "MathUtils.hpp"
#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 Viewer_destroy(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE TSceneManager *Viewer_getSceneManager(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE TRenderTarget* Viewer_createRenderTarget(TViewer *viewer, intptr_t texture, uint32_t width, uint32_t height);
EMSCRIPTEN_KEEPALIVE void Viewer_destroyRenderTarget(TViewer *viewer, TRenderTarget* tRenderTarget);
EMSCRIPTEN_KEEPALIVE TSwapChain *Viewer_createSwapChain(TViewer *viewer, const void *const window);
EMSCRIPTEN_KEEPALIVE TSwapChain *Viewer_createHeadlessSwapChain(TViewer *viewer, uint32_t width, uint32_t height);
EMSCRIPTEN_KEEPALIVE void Viewer_destroySwapChain(TViewer *viewer, TSwapChain* swapChain);
EMSCRIPTEN_KEEPALIVE void Viewer_render(
TViewer *viewer);
EMSCRIPTEN_KEEPALIVE void Viewer_capture(
TViewer *viewer,
TView *view,
TSwapChain *swapChain,
uint8_t *pixelBuffer,
void (*callback)(void));
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderTarget(
TViewer *viewer,
TView *view,
TSwapChain *swapChain,
TRenderTarget *renderTarget,
uint8_t *pixelBuffer,
void (*callback)(void));
EMSCRIPTEN_KEEPALIVE TView* Viewer_createView(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE TView* Viewer_getViewAt(TViewer *viewer, int index);
EMSCRIPTEN_KEEPALIVE void Viewer_setMainCamera(TViewer *tViewer, TView *tView);
EMSCRIPTEN_KEEPALIVE TSwapChain* Viewer_getSwapChainAt(TViewer *tViewer, int index);
EMSCRIPTEN_KEEPALIVE void Viewer_setViewRenderable(TViewer *viewer, TSwapChain *swapChain, TView* view, bool renderable);
// Engine
EMSCRIPTEN_KEEPALIVE TEngine *Viewer_getEngine(TViewer* viewer);
EMSCRIPTEN_KEEPALIVE TCamera *Engine_getCameraComponent(TEngine* tEngine, EntityId entityId);
EMSCRIPTEN_KEEPALIVE void clear_background_image(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE void set_background_image(TViewer *viewer, const char *path, bool fillHeight);
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 load_skybox(TViewer *viewer, const char *skyboxPath);
EMSCRIPTEN_KEEPALIVE void Viewer_loadIbl(TViewer *viewer, const char *iblPath, float intensity);
EMSCRIPTEN_KEEPALIVE void create_ibl(TViewer *viewer, float r, float g, float b, float intensity);
EMSCRIPTEN_KEEPALIVE void rotate_ibl(TViewer *viewer, float *rotationMatrix);
EMSCRIPTEN_KEEPALIVE void remove_skybox(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE void remove_ibl(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE EntityId add_light(
TViewer *viewer,
uint8_t type,
float colour,
float intensity,
float posX,
float posY,
float posZ,
float dirX,
float dirY,
float dirZ,
float falloffRadius,
float spotLightConeInner,
float spotLightConeOuter,
float sunAngularRadius,
float sunHaloSize,
float sunHaloFallof,
bool shadows);
EMSCRIPTEN_KEEPALIVE void remove_light(TViewer *viewer, EntityId entityId);
EMSCRIPTEN_KEEPALIVE void clear_lights(TViewer *viewer);
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 get_main_camera(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE void set_frame_interval(TViewer *viewer, float interval);
EMSCRIPTEN_KEEPALIVE void queue_relative_position_update_world_axis(TSceneManager *sceneManager, EntityId entity, float viewportX, float viewportY, float x, float y, float z);
EMSCRIPTEN_KEEPALIVE void queue_position_update_from_viewport_coords(TSceneManager *sceneManager, TView *view, EntityId entity, float viewportX, float viewportY);
EMSCRIPTEN_KEEPALIVE TTransformManager *Engine_getTransformManager(TEngine *engine);
EMSCRIPTEN_KEEPALIVE TRenderableManager *Engine_getRenderableManager(TEngine *engine);
EMSCRIPTEN_KEEPALIVE TCamera *Engine_getCameraComponent(TEngine *engine, EntityId entity);
EMSCRIPTEN_KEEPALIVE TEntityManager *Engine_getEntityManager(TEngine *engine);
EMSCRIPTEN_KEEPALIVE void ios_dummy();
EMSCRIPTEN_KEEPALIVE void thermion_flutter_free(void *ptr);
EMSCRIPTEN_KEEPALIVE void add_collision_component(TSceneManager *sceneManager, EntityId entityId, void (*callback)(const EntityId entityId1, const EntityId entityId2), bool affectsCollidingTransform);
EMSCRIPTEN_KEEPALIVE void remove_collision_component(TSceneManager *sceneManager, EntityId entityId);
EMSCRIPTEN_KEEPALIVE void test_collisions(TSceneManager *sceneManager, EntityId entity);
EMSCRIPTEN_KEEPALIVE Aabb2 get_bounding_box(TSceneManager *sceneManager, TView *view, EntityId entity);
EMSCRIPTEN_KEEPALIVE void get_bounding_box_to_out(TSceneManager *sceneManager, TView *view, EntityId entity, float *minX, float *minY, float *maxX, float *maxY);
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 *const create_texture(TSceneManager *sceneManager, uint8_t *data, size_t length);
EMSCRIPTEN_KEEPALIVE void destroy_texture(TSceneManager *sceneManager, void *const texture);
EMSCRIPTEN_KEEPALIVE void apply_texture_to_material(TSceneManager *sceneManager, EntityId entity, void *const texture, const char *parameterName, int materialIndex);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,115 @@
#ifndef _DART_FILAMENT_FFI_API_H
#define _DART_FILAMENT_FFI_API_H
#include "ThermionDartApi.h"
#include "TView.h"
#include "TMaterialProvider.h"
#ifdef __cplusplus
namespace thermion
{
extern "C"
{
#endif
///
/// This header replicates most of the methods in ThermionDartApi.h.
/// It represents the interface for:
/// - invoking those methods that must be called on the main Filament engine thread
/// - setting up a render loop
///
typedef int32_t EntityId;
typedef void (*FilamentRenderCallback)(void *const owner);
EMSCRIPTEN_KEEPALIVE void Viewer_createOnRenderThread(
void *const context,
void *const platform,
const char *uberArchivePath,
const void *const loader,
void (*renderCallback)(void *const renderCallbackOwner),
void *const renderCallbackOwner,
void (*callback)(TViewer *viewer));
EMSCRIPTEN_KEEPALIVE void Viewer_destroyOnRenderThread(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE void Viewer_createSwapChainRenderThread(TViewer *viewer, void *const surface, void (*onComplete)(TSwapChain *));
EMSCRIPTEN_KEEPALIVE void Viewer_createHeadlessSwapChainRenderThread(TViewer *viewer, uint32_t width, uint32_t height, void (*onComplete)(TSwapChain *));
EMSCRIPTEN_KEEPALIVE void Viewer_destroySwapChainRenderThread(TViewer *viewer, TSwapChain *swapChain, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Viewer_renderRenderThread(TViewer *viewer, TView *view, TSwapChain *swapChain);
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderThread(TViewer *viewer, TView *view, TSwapChain *swapChain, uint8_t *out, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Viewer_captureRenderTargetRenderThread(TViewer *viewer, TView *view, TSwapChain *swapChain, TRenderTarget *renderTarget, uint8_t *out, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Viewer_requestFrameRenderThread(TViewer *viewer, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Viewer_loadIblRenderThread(TViewer *viewer, const char *iblPath, float intensity, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void Viewer_createRenderTargetRenderThread(TViewer *viewer, intptr_t texture, uint32_t width, uint32_t height, void (*onComplete)(TRenderTarget *));
EMSCRIPTEN_KEEPALIVE void View_setToneMappingRenderThread(TView *tView, TEngine *tEngine, thermion::ToneMapping toneMapping);
EMSCRIPTEN_KEEPALIVE void View_setBloomRenderThread(TView *tView, double bloom);
FilamentRenderCallback make_render_callback_fn_pointer(FilamentRenderCallback);
EMSCRIPTEN_KEEPALIVE void set_rendering_render_thread(TViewer *viewer, bool rendering, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void set_frame_interval_render_thread(TViewer *viewer, float frameInterval);
EMSCRIPTEN_KEEPALIVE void set_background_color_render_thread(TViewer *viewer, const float r, const float g, const float b, const float a);
EMSCRIPTEN_KEEPALIVE void clear_background_image_render_thread(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE void set_background_image_render_thread(TViewer *viewer, const char *path, bool fillHeight, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void set_background_image_position_render_thread(TViewer *viewer, float x, float y, bool clamp);
EMSCRIPTEN_KEEPALIVE void load_skybox_render_thread(TViewer *viewer, const char *skyboxPath, void (*onComplete)());
EMSCRIPTEN_KEEPALIVE void remove_skybox_render_thread(TViewer *viewer);
EMSCRIPTEN_KEEPALIVE void SceneManager_createGeometryRenderThread(
TSceneManager *sceneManager,
float *vertices,
int numVertices,
float *normals,
int numNormals,
float *uvs,
int numUvs,
uint16_t *indices,
int numIndices,
int primitiveType,
TMaterialInstance **materialInstances,
int materialInstanceCount,
bool keepData,
void (*callback)(TSceneAsset *));
EMSCRIPTEN_KEEPALIVE void SceneManager_loadGlbFromBufferRenderThread(TSceneManager *sceneManager, const uint8_t *const data, size_t length, int numInstances, bool keepData, int priority, int layer, bool loadResourcesAsync, void (*callback)(TSceneAsset *));
EMSCRIPTEN_KEEPALIVE void SceneManager_createUnlitMaterialInstanceRenderThread(TSceneManager *sceneManager, void (*callback)(TMaterialInstance *));
EMSCRIPTEN_KEEPALIVE void SceneManager_createUnlitFixedSizeMaterialInstanceRenderThread(TSceneManager *sceneManager, void (*callback)(TMaterialInstance *));
EMSCRIPTEN_KEEPALIVE void SceneManager_loadGlbRenderThread(TSceneManager *sceneManager, const char *assetPath, int numInstances, bool keepData, void (*callback)(TSceneAsset *));
EMSCRIPTEN_KEEPALIVE void SceneManager_loadGltfRenderThread(TSceneManager *sceneManager, const char *assetPath, const char *relativePath, bool keepData, void (*callback)(TSceneAsset *));
EMSCRIPTEN_KEEPALIVE void *SceneManager_destroyAllRenderThread(TSceneManager *tSceneManager, void (*callback)());
EMSCRIPTEN_KEEPALIVE void *SceneManager_destroyAssetRenderThread(TSceneManager *tSceneManager, TSceneAsset *sceneAsset, void (*callback)());
EMSCRIPTEN_KEEPALIVE void SceneAsset_createInstanceRenderThread(TSceneAsset *asset, TMaterialInstance **tMaterialInstances, int materialInstanceCount, void (*callback)(TSceneAsset *));
EMSCRIPTEN_KEEPALIVE void MaterialProvider_createMaterialInstanceRenderThread(TMaterialProvider *tMaterialProvider, TMaterialKey *tKey, void (*callback)(TMaterialInstance*));
EMSCRIPTEN_KEEPALIVE void AnimationManager_updateBoneMatricesRenderThread(
TAnimationManager *tAnimationManager,
TSceneAsset *sceneAsset,
void (*callback)(bool));
EMSCRIPTEN_KEEPALIVE void AnimationManager_setMorphTargetWeightsRenderThread(
TAnimationManager *tAnimationManager,
EntityId entityId,
const float *const morphData,
int numWeights,
void (*callback)(bool));
EMSCRIPTEN_KEEPALIVE void update_bone_matrices_render_thread(TSceneManager *sceneManager,
EntityId asset, void (*callback)(bool));
EMSCRIPTEN_KEEPALIVE void set_bone_transform_render_thread(
TSceneManager *sceneManager,
EntityId asset,
int skinIndex,
int boneIndex,
const float *const transform,
void (*callback)(bool));
EMSCRIPTEN_KEEPALIVE void set_post_processing_render_thread(TViewer *viewer, bool enabled);
EMSCRIPTEN_KEEPALIVE void reset_to_rest_pose_render_thread(TSceneManager *sceneManager, EntityId entityId, void (*callback)());
EMSCRIPTEN_KEEPALIVE void unproject_texture_render_thread(TViewer *viewer, EntityId entity, uint8_t *input, uint32_t inputWidth, uint32_t inputHeight, uint8_t *out, uint32_t outWidth, uint32_t outHeight, void (*callback)());
#ifdef __cplusplus
}
}
#endif
#endif // _DART_FILAMENT_FFI_API_H

View File

@@ -1,7 +1,5 @@
#pragma once
#include "Log.hpp"
#include <chrono>
#include <variant>
@@ -18,10 +16,11 @@
#include <math/norm.h>
#include <gltfio/Animator.h>
#include <gltfio/AssetLoader.h>
#include <gltfio/ResourceLoader.h>
#include <gltfio/math.h>
#include <utils/NameComponentManager.h>
#include <utils/SingleInstanceComponentManager.h>
#include "Log.hpp"
template class std::vector<float>;
namespace thermion
@@ -170,7 +169,6 @@ namespace thermion
if (std::holds_alternative<FilamentInstance *>(animationComponent.target))
{
auto target = std::get<FilamentInstance *>(animationComponent.target);
auto animator = target->getAnimator();
auto &gltfAnimations = animationComponent.gltfAnimations;
@@ -225,7 +223,6 @@ namespace thermion
if (elapsedInSecs >= (animationStatus.durationInSecs + animationStatus.fadeInInSecs + animationStatus.fadeOutInSecs))
{
if(!animationStatus.loop) {
Log("Bone animation %d finished", i);
boneAnimations.erase(boneAnimations.begin() + i);
continue;
}

View File

@@ -8,5 +8,5 @@ GRID_PACKAGE:
GRID_GRID_OFFSET:
.int 0
GRID_GRID_SIZE:
.int 43432
.int 44564

View File

@@ -8,5 +8,5 @@ _GRID_PACKAGE:
_GRID_GRID_OFFSET:
.int 0
_GRID_GRID_SIZE:
.int 43432
.int 44564

File diff suppressed because it is too large Load Diff

View File

@@ -8,5 +8,5 @@ UNLIT_FIXED_SIZE_PACKAGE:
UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_OFFSET:
.int 0
UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_SIZE:
.int 39924
.int 41110

View File

@@ -8,5 +8,5 @@ _UNLIT_FIXED_SIZE_PACKAGE:
_UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_OFFSET:
.int 0
_UNLIT_FIXED_SIZE_UNLIT_FIXED_SIZE_SIZE:
.int 39924
.int 41110

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,172 @@
#pragma once
#include <mutex>
#include <vector>
#include <filament/Engine.h>
#include <filament/Scene.h>
#include "c_api/APIBoundaryTypes.h"
#include "components/CollisionComponentManager.hpp"
#include "components/AnimationComponentManager.hpp"
#include "GltfSceneAssetInstance.hpp"
#include "GltfSceneAsset.hpp"
#include "SceneAsset.hpp"
namespace thermion
{
using namespace filament;
using namespace filament::gltfio;
using namespace utils;
using std::string;
using std::unique_ptr;
using std::vector;
/// @brief
class AnimationManager
{
public:
AnimationManager(
Engine *engine,
Scene *scene);
~AnimationManager();
void update();
/// @brief
/// @param asset
/// @param childEntity
/// @return
vector<string> getMorphTargetNames(GltfSceneAsset *asset, EntityId childEntity);
/// @brief
/// @param instance
/// @param skinIndex
/// @return
vector<Entity> getBoneEntities(GltfSceneAssetInstance *instance, int skinIndex);
/// @brief
/// @param sceneAsset
/// @param morphData
/// @param morphIndices
/// @param numMorphTargets
/// @param numFrames
/// @param frameLengthInMs
/// @return
bool setMorphAnimationBuffer(
utils::Entity entity,
const float *const morphData,
const uint32_t *const morphIndices,
int numMorphTargets,
int numFrames,
float frameLengthInMs);
/// @brief
/// @param entityId
void clearMorphAnimationBuffer(
utils::Entity entity);
/// @brief
/// @param instance
/// @param skinIndex
/// @param boneIndex
/// @return
math::mat4f getInverseBindMatrix(GltfSceneAssetInstance *instance, int skinIndex, int boneIndex);
/// @brief Set the local transform for the bone at boneIndex/skinIndex in the given entity.
/// @param entityId the parent entity
/// @param entityName the name of the mesh under entityId for which the bone will be set.
/// @param skinIndex the index of the joint skin. Currently only 0 is supported.
/// @param boneName the name of the bone
/// @param transform the 4x4 matrix representing the local transform for the bone
/// @return true if the transform was successfully set, false otherwise
bool setBoneTransform(GltfSceneAssetInstance *instance, int skinIndex, int boneIndex, math::mat4f transform);
/// @brief Immediately start animating the bone at [boneIndex] under the parent instance [entity] at skin [skinIndex].
/// @param entity the mesh entity to animate
/// @param frameData frame data as quaternions
/// @param numFrames the number of frames
/// @param boneName the name of the bone to animate
/// @param frameLengthInMs the length of each frame in ms
/// @return true if the bone animation was successfully enqueued
bool addBoneAnimation(
GltfSceneAssetInstance *instance,
int skinIndex,
int boneIndex,
const float *const frameData,
int numFrames,
float frameLengthInMs,
float fadeOutInSecs,
float fadeInInSecs,
float maxDelta);
/// @brief
/// @param instance
/// @param skinIndex
/// @return
std::vector<math::mat4f> getBoneRestTranforms(GltfSceneAssetInstance *instance, int skinIndex);
/// @brief
/// @param instance
void resetToRestPose(GltfSceneAssetInstance *instance);
/// @brief
/// @param instance
void updateBoneMatrices(GltfSceneAssetInstance *instance);
/// @brief
/// @param instance
/// @param animationIndex
/// @param loop
/// @param reverse
/// @param replaceActive
/// @param crossfade
/// @param startOffset
void playGltfAnimation(GltfSceneAssetInstance *instance, int animationIndex, bool loop, bool reverse, bool replaceActive, float crossfade = 0.3f, float startOffset = 0.0f);
/// @brief
/// @param instance
/// @param animationIndex
void stopGltfAnimation(GltfSceneAssetInstance *instance, int animationIndex);
/// @brief
/// @param instance
/// @param weights
/// @param count
void setMorphTargetWeights(utils::Entity entity, const float *const weights, int count);
/// @brief
/// @param instance
/// @param animationIndex
/// @param animationFrame
void setGltfAnimationFrame(GltfSceneAssetInstance *instance, int animationIndex, int animationFrame);
/// @brief
/// @param instance
/// @return
vector<string> getGltfAnimationNames(GltfSceneAssetInstance *instance);
/// @brief
/// @param instance
/// @param animationIndex
/// @return
float getGltfAnimationDuration(GltfSceneAssetInstance *instance, int animationIndex);
/// @brief
/// @param entity
/// @return
bool addAnimationComponent(EntityId entity);
/// @brief
/// @param entity
void removeAnimationComponent(EntityId entity);
private:
Engine *_engine = nullptr;
Scene *_scene = nullptr;
std::mutex _mutex;
std::unique_ptr<AnimationComponentManager> _animationComponentManager = std::nullptr_t();
};
}

View File

@@ -17,9 +17,8 @@
namespace thermion
{
using namespace filament;
using namespace filament;
// CustomGeometry.h
class CustomGeometry {
public:
CustomGeometry(
@@ -31,6 +30,7 @@ public:
uint32_t numUvs,
uint16_t* indices,
uint32_t numIndices,
MaterialInstance* materialInstance,
RenderableManager::PrimitiveType primitiveType,
Engine* engine);
~CustomGeometry();
@@ -40,6 +40,8 @@ public:
private:
Engine* _engine;
MaterialInstance* _materialInstance = nullptr;
VertexBuffer* vertexBuffer;
IndexBuffer* indexBuffer;

View File

@@ -0,0 +1,143 @@
#pragma once
#include <memory>
#include <filament/Engine.h>
#include <filament/RenderableManager.h>
#include <filament/VertexBuffer.h>
#include <filament/IndexBuffer.h>
#include <gltfio/MaterialProvider.h>
#include "scene/SceneAsset.hpp"
namespace thermion
{
using namespace filament;
class GeometrySceneAsset : public SceneAsset
{
public:
GeometrySceneAsset(bool isInstance,
Engine *engine,
VertexBuffer *vertexBuffer,
IndexBuffer *indexBuffer,
MaterialInstance **materialInstances,
size_t materialInstanceCount,
RenderableManager::PrimitiveType primitiveType,
Box boundingBox);
~GeometrySceneAsset();
SceneAsset *createInstance(MaterialInstance **materialInstances = nullptr, size_t materialInstanceCount = 0) override;
SceneAssetType getType() override
{
return SceneAsset::SceneAssetType::Geometry;
}
bool isInstance() override
{
return _isInstance;
}
utils::Entity getEntity() override
{
return _entity;
}
MaterialInstance **getMaterialInstances() override
{
return _materialInstances;
}
size_t getMaterialInstanceCount() override
{
return _materialInstanceCount;
}
const Box &getBoundingBox() const { return _boundingBox; }
VertexBuffer *getVertexBuffer() const { return _vertexBuffer; }
IndexBuffer *getIndexBuffer() const { return _indexBuffer; }
void addAllEntities(Scene *scene) override
{
scene->addEntity(_entity);
}
void removeAllEntities(Scene *scene) override
{
scene->remove(_entity);
}
void setPriority(RenderableManager &rm, int priority) override
{
auto renderableInstance = rm.getInstance(_entity);
rm.setPriority(renderableInstance, priority);
}
void setLayer(RenderableManager &rm, int layer) override
{
auto renderableInstance = rm.getInstance(_entity);
rm.setLayerMask(renderableInstance, 0xFF, 1u << (uint8_t)layer);
}
SceneAsset *getInstanceByEntity(utils::Entity entity) override
{
for (auto &instance : _instances)
{
if (instance->getEntity() == entity)
{
return instance.get();
}
}
return std::nullptr_t();
}
SceneAsset *getInstanceAt(size_t index) override
{
auto &asset = _instances[index];
return asset.get();
}
size_t getInstanceCount() override
{
return _instances.size();
}
size_t getChildEntityCount() override
{
return 0;
}
const Entity *getChildEntities() override
{
return nullptr;
}
Entity findEntityByName(const char *name) override
{
return Entity(); // not currently implemented
}
static std::unique_ptr<GeometrySceneAsset> create(
float *vertices, uint32_t numVertices,
float *normals, uint32_t numNormals,
float *uvs, uint32_t numUvs,
uint16_t *indices, uint32_t numIndices,
MaterialInstance *materialInstance,
RenderableManager::PrimitiveType primitiveType,
Engine *engine);
private:
Engine *_engine = nullptr;
VertexBuffer *_vertexBuffer = nullptr;
IndexBuffer *_indexBuffer = nullptr;
MaterialInstance **_materialInstances = nullptr;
size_t _materialInstanceCount = 0;
Box _boundingBox;
bool _isInstance = false;
utils::Entity _entity;
RenderableManager::PrimitiveType _primitiveType;
std::vector<std::unique_ptr<GeometrySceneAsset>> _instances;
};
} // namespace thermion

View File

@@ -0,0 +1,308 @@
#pragma once
#include <memory>
#include <vector>
#include <filament/Engine.h>
#include <filament/RenderableManager.h>
#include <filament/VertexBuffer.h>
#include <filament/IndexBuffer.h>
#include <filament/geometry/SurfaceOrientation.h>
#include <filament/Box.h>
#include <gltfio/MaterialProvider.h>
#include "GeometrySceneAsset.hpp"
#include "Log.hpp"
namespace thermion
{
class GeometrySceneAssetBuilder
{
public:
GeometrySceneAssetBuilder(filament::Engine *engine) : mEngine(engine) {}
GeometrySceneAssetBuilder &vertices(const float *vertices, uint32_t count)
{
mVertices->resize(count);
std::copy(vertices, vertices + count, mVertices->data());
mNumVertices = count;
return *this;
}
GeometrySceneAssetBuilder &normals(const float *normals, uint32_t count)
{
if (normals)
{
mNormals->resize(count);
std::copy(normals, normals + count, mNormals->data());
}
else
{
mNormals->clear();
}
mNumNormals = count;
return *this;
}
GeometrySceneAssetBuilder &uvs(const float *uvs, uint32_t count)
{
if (uvs)
{
mUVs->resize(count);
std::copy(uvs, uvs + count, mUVs->data());
}
else
{
mUVs->clear();
}
mNumUVs = count;
return *this;
}
GeometrySceneAssetBuilder &indices(const uint16_t *indices, uint32_t count)
{
mIndices->resize(count);
std::copy(indices, indices + count, mIndices->data());
mNumIndices = count;
return *this;
}
GeometrySceneAssetBuilder &materials(filament::MaterialInstance **materials, size_t materialInstanceCount)
{
mMaterialInstances = materials;
mMaterialInstanceCount = materialInstanceCount;
return *this;
}
GeometrySceneAssetBuilder &primitiveType(filament::RenderableManager::PrimitiveType type)
{
mPrimitiveType = type;
return *this;
}
std::unique_ptr<GeometrySceneAsset> build()
{
Log("Starting build. Validating inputs...");
if (!validate())
{
Log("Validation failed!");
return nullptr;
}
Log("Creating buffers...");
auto [vertexBuffer, indexBuffer] = createBuffers();
if (!vertexBuffer || !indexBuffer)
{
Log("Failed to create buffers: VB=%p, IB=%p", vertexBuffer, indexBuffer);
return nullptr;
}
Log("Buffers created successfully: VB=%p, IB=%p", vertexBuffer, indexBuffer);
Log("Creating entity...");
auto entity = utils::EntityManager::get().create();
Log("Entity created: %d", entity.getId());
Box boundingBox = computeBoundingBox();
Log("Computed bounding box: min={%f,%f,%f}, max={%f,%f,%f}",
boundingBox.getMin().x, boundingBox.getMin().y, boundingBox.getMin().z,
boundingBox.getMax().x, boundingBox.getMax().y, boundingBox.getMax().z);
auto asset = std::make_unique<GeometrySceneAsset>(
false,
mEngine,
vertexBuffer,
indexBuffer,
mMaterialInstances,
mMaterialInstanceCount,
mPrimitiveType,
boundingBox);
Log("Asset created: %p", asset.get());
return asset;
}
private:
Box computeBoundingBox()
{
float minX = FLT_MAX, minY = FLT_MAX, minZ = FLT_MAX;
float maxX = -FLT_MAX, maxY = -FLT_MAX, maxZ = -FLT_MAX;
Box box;
for (uint32_t i = 0; i < mNumVertices; i += 3)
{
minX = std::min(mVertices->at(i), minX);
minY = std::min(mVertices->at(i + 1), minY);
minZ = std::min(mVertices->at(i + 2), minZ);
maxX = std::max(mVertices->at(i), maxX);
maxY = std::max(mVertices->at(i + 1), maxY);
maxZ = std::max(mVertices->at(i + 2), maxZ);
}
const filament::math::float3 min {minX, minY, minZ};
const filament::math::float3 max {maxX, maxY, maxZ};
box.set(min, max);
return box;
}
std::pair<filament::VertexBuffer *, filament::IndexBuffer *> createBuffers()
{
auto indexBuffer = IndexBuffer::Builder()
.indexCount(mNumIndices)
.bufferType(IndexBuffer::IndexType::USHORT)
.build(*mEngine);
indexBuffer->setBuffer(*mEngine,
IndexBuffer::BufferDescriptor(
mIndices->data(),
mNumIndices * sizeof(uint16_t),
[](void *, size_t, void *data)
{
delete static_cast<std::vector<float> *>(data);
},
mIndices));
if (mUVs->empty())
{
mUVs->resize(mNumVertices);
std::fill(mUVs->begin(), mUVs->end(), 0.0f);
}
auto dummyColors = new std::vector<filament::math::float4>(
mNumVertices, filament::math::float4{1.0f, 1.0f, 1.0f, 1.0f});
auto vertexBufferBuilder =
VertexBuffer::Builder()
.vertexCount(mNumVertices)
.attribute(VertexAttribute::POSITION, 0, VertexBuffer::AttributeType::FLOAT3)
.attribute(VertexAttribute::UV0, 1, VertexBuffer::AttributeType::FLOAT2)
.attribute(VertexAttribute::UV1, 2, VertexBuffer::AttributeType::FLOAT2)
.attribute(VertexAttribute::COLOR, 3, VertexBuffer::AttributeType::FLOAT4);
if (!mNormals->empty())
{
vertexBufferBuilder.bufferCount(5)
.attribute(VertexAttribute::TANGENTS, 4, VertexBuffer::AttributeType::FLOAT4);
}
else
{
vertexBufferBuilder = vertexBufferBuilder.bufferCount(4);
}
auto vertexBuffer = vertexBufferBuilder.build(*mEngine);
vertexBuffer->setBufferAt(*mEngine, 0,
VertexBuffer::BufferDescriptor(
mVertices->data(), mNumVertices * sizeof(float),
[](void *, size_t, void *) {}));
vertexBuffer->setBufferAt(*mEngine, 1,
VertexBuffer::BufferDescriptor(
mUVs->data(), mUVs->size() * sizeof(float),
[](void *, size_t, void *data)
{
},
mUVs));
vertexBuffer->setBufferAt(*mEngine, 2,
VertexBuffer::BufferDescriptor(
mUVs->data(), mUVs->size() * sizeof(float),
[](void *, size_t, void *data) {
delete static_cast<std::vector<float> *>(data);
},
mUVs));
vertexBuffer->setBufferAt(*mEngine, 3,
VertexBuffer::BufferDescriptor(
dummyColors->data(), dummyColors->size() * sizeof(math::float4),
[](void *, size_t, void *data)
{
delete static_cast<std::vector<math::float4> *>(data);
},
dummyColors));
if (!mNormals->empty())
{
assert(mPrimitiveType == RenderableManager::PrimitiveType::TRIANGLES);
std::vector<filament::math::ushort3> triangles;
for (uint32_t i = 0; i < mNumIndices; i += 3)
{
triangles.push_back({mIndices->at(i),
mIndices->at(i + 1),
mIndices->at(i + 2)});
}
auto &builder = geometry::SurfaceOrientation::Builder()
.vertexCount(mNumVertices)
.normals((filament::math::float3 *)mNormals->data())
.positions((filament::math::float3 *)mVertices->data())
.triangleCount(triangles.size())
.triangles(triangles.data());
auto orientation = builder.build();
auto quats = new std::vector<filament::math::quatf>(mNumVertices);
orientation->getQuats(quats->data(), mNumVertices);
vertexBuffer->setBufferAt(*mEngine, 4,
VertexBuffer::BufferDescriptor(
quats->data(), quats->size() * sizeof(math::quatf),
[](void *, size_t, void *data)
{
delete static_cast<std::vector<math::quatf> *>(data);
},
quats));
}
return {vertexBuffer, indexBuffer};
}
bool validate() const
{
if (!mEngine)
{
Log("Validation failed: No engine");
return false;
}
if (mVertices->empty() || mNumVertices == 0)
{
Log("Validation failed: No vertices (empty=%d, count=%d)", mVertices->empty(), mNumVertices);
return false;
}
if (mNumNormals > 0 && !mNormals->empty() && mNumNormals != mNumVertices)
{
Log("Validation failed: Normal count mismatch (normals=%d, vertices=%d)", mNumNormals, mNumVertices);
return false;
}
if (mNumUVs > 0 && !mUVs->empty() && mNumUVs != mNumVertices)
{
Log("Validation failed: UV count mismatch (uvs=%d, vertices=%d)", mNumUVs, mNumVertices);
return false;
}
if (mIndices->empty() || mNumIndices == 0)
{
Log("Validation failed: No indices (empty=%d, count=%d)", mIndices->empty(), mNumIndices);
return false;
}
Log("Validation passed: vertices=%d, normals=%s, uvs=%d, indices=%d",
mNumVertices,
(!mNormals->empty() ? "yes" : "no"),
mNumUVs,
mNumIndices);
return true;
}
filament::Engine *mEngine = nullptr;
std::vector<float> *mVertices = new std::vector<float>();
std::vector<float> *mNormals = new std::vector<float>();
std::vector<float> *mUVs = new std::vector<float>();
std::vector<uint16_t> *mIndices = new std::vector<uint16_t>;
uint32_t mNumVertices = 0;
uint32_t mNumNormals = 0;
uint32_t mNumUVs = 0;
uint32_t mNumIndices = 0;
filament::MaterialInstance **mMaterialInstances = nullptr;
size_t mMaterialInstanceCount = 0;
filament::gltfio::MaterialProvider *mMaterialProvider = nullptr;
filament::RenderableManager::PrimitiveType mPrimitiveType =
filament::RenderableManager::PrimitiveType::TRIANGLES;
};
} // namespace thermion

View File

@@ -0,0 +1,201 @@
#pragma once
#include <utils/Entity.h>
#include <filament/Engine.h>
#include <filament/Material.h>
#include <filament/MaterialInstance.h>
#include <filament/Scene.h>
#include <filament/Camera.h>
#include <filament/View.h>
#include <filament/Viewport.h>
#include <filament/RenderableManager.h>
#include <gltfio/AssetLoader.h>
#include <gltfio/FilamentAsset.h>
#include <gltfio/FilamentInstance.h>
#include <gltfio/ResourceLoader.h>
#include <filament/IndexBuffer.h>
#include <filament/InstanceBuffer.h>
#include "c_api/ThermionDartApi.h"
#include "scene/SceneAsset.hpp"
namespace thermion
{
using namespace filament;
using namespace utils;
class Gizmo : public SceneAsset
{
public:
Gizmo(Engine *engine, View *view, Scene *scene, Material *material);
~Gizmo() override;
enum Axis
{
X,
Y,
Z
};
enum GizmoPickResultType {
AxisX,
AxisY,
AxisZ,
Parent,
None
};
typedef void (*GizmoPickCallback)(Gizmo::GizmoPickResultType result, float x, float y, float z);
void pick(uint32_t x, uint32_t y, GizmoPickCallback callback);
bool isGizmoEntity(Entity entity);
SceneAssetType getType() override { return SceneAssetType::Gizmo; }
utils::Entity getEntity() override { return _entities[0]; }
bool isInstance() override { return false; }
SceneAsset *createInstance(MaterialInstance **materialInstances, size_t materialInstanceCount) override { return nullptr; }
MaterialInstance **getMaterialInstances() override { return _materialInstances.data(); }
size_t getMaterialInstanceCount() override { return _materialInstances.size(); }
void addAllEntities(Scene *scene) override
{
for (const auto &entity : _entities)
{
if (entity.isNull())
{
continue;
}
scene->addEntity(entity);
}
}
void removeAllEntities(Scene *scene) override
{
for (const auto &entity : _entities)
{
scene->remove(entity);
}
}
size_t getInstanceCount() override { return 0; }
SceneAsset *getInstanceByEntity(utils::Entity entity) override { return nullptr; }
SceneAsset *getInstanceAt(size_t index) override { return nullptr; }
size_t getChildEntityCount() override { return _entities.size() - 1; }
const Entity *getChildEntities() override { return _entities.data() + 1; }
Entity findEntityByName(const char *name) override
{
return utils::Entity::import(0);
}
void setPriority(RenderableManager &rm, int mask) override
{
}
void setLayer(RenderableManager &rm, int layer) override
{
}
void highlight(Gizmo::Axis axis);
void unhighlight(Gizmo::Axis axis);
private:
class PickCallbackHandler
{
public:
PickCallbackHandler(Gizmo *gizmo, GizmoPickCallback callback)
: _gizmo(gizmo), _callback(callback) {}
void handle(filament::View::PickingQueryResult const &result)
{
_gizmo->unhighlight(Gizmo::Axis::X);
_gizmo->unhighlight(Gizmo::Axis::Y);
_gizmo->unhighlight(Gizmo::Axis::Z);
Gizmo::GizmoPickResultType resultType;
if (result.renderable == _gizmo->_parent)
{
resultType = Gizmo::GizmoPickResultType::Parent;
}
else if (result.renderable == _gizmo->_x || result.renderable == _gizmo->_xHitTest)
{
resultType = Gizmo::GizmoPickResultType::AxisX;
_gizmo->highlight(Gizmo::Axis::X);
}
else if (result.renderable == _gizmo->_y || result.renderable == _gizmo->_yHitTest)
{
_gizmo->highlight(Gizmo::Axis::Y);
resultType = Gizmo::GizmoPickResultType::AxisY;
}
else if (result.renderable == _gizmo->_z || result.renderable == _gizmo->_zHitTest)
{
_gizmo->highlight(Gizmo::Axis::Z);
resultType = Gizmo::GizmoPickResultType::AxisZ;
} else {
resultType = Gizmo::GizmoPickResultType::None;
}
_callback(resultType, result.fragCoords.x, result.fragCoords.y, result.fragCoords.z);
}
private:
Gizmo *_gizmo;
GizmoPickCallback _callback;
};
Entity createParentEntity();
Entity createHitTestEntity(Gizmo::Axis axis, Entity parent);
Entity createAxisEntity(Gizmo::Axis axis, Entity parent);
math::mat4f getRotationForAxis(Gizmo::Axis axis);
Entity getEntityForAxis(Gizmo::Axis axis)
{
switch (axis)
{
case Gizmo::Axis::X:
return _x;
case Gizmo::Axis::Y:
return _y;
case Gizmo::Axis::Z:
return _z;
}
}
Engine *_engine;
Scene *_scene;
View *_view;
Material *_material;
utils::Entity _parent;
utils::Entity _x;
utils::Entity _y;
utils::Entity _z;
utils::Entity _xHitTest;
utils::Entity _yHitTest;
utils::Entity _zHitTest;
std::vector<utils::Entity> _entities;
std::vector<MaterialInstance *> _materialInstances;
math::float4 activeColors[3]{
math::float4{1.0f, 1.0f, 0.0f, 0.5f},
math::float4{1.0f, 1.0f, 0.0f, 0.5f},
math::float4{1.0f, 1.0f, 0.0f, 0.5f},
};
math::float4 inactiveColors[3]{
math::float4{1.0f, 0.0f, 0.0f, 1.0f},
math::float4{0.0f, 1.0f, 0.0f, 1.0f},
math::float4{0.0f, 0.0f, 1.0f, 1.0f},
};
};
}

View File

@@ -0,0 +1,163 @@
#pragma once
#include <memory>
#include <vector>
#include <filament/Engine.h>
#include <filament/RenderableManager.h>
#include <filament/VertexBuffer.h>
#include <filament/IndexBuffer.h>
#include <gltfio/AssetLoader.h>
#include <gltfio/FilamentAsset.h>
#include <gltfio/MaterialProvider.h>
#include "scene/GltfSceneAssetInstance.hpp"
#include "components/AnimationComponentManager.hpp"
#include "components/CollisionComponentManager.hpp"
#include "scene/SceneAsset.hpp"
namespace thermion
{
using namespace filament;
class GltfSceneAsset : public SceneAsset
{
public:
GltfSceneAsset(
gltfio::FilamentAsset *asset,
gltfio::AssetLoader *assetLoader,
Engine *engine,
MaterialInstance **materialInstances = nullptr,
size_t materialInstanceCount = 0,
int instanceIndex = -1) : _asset(asset),
_assetLoader(assetLoader),
_engine(engine),
_materialInstances(materialInstances),
_materialInstanceCount(materialInstanceCount)
{
}
~GltfSceneAsset();
SceneAsset *createInstance(MaterialInstance **materialInstances = nullptr, size_t materialInstanceCount = 0) override;
SceneAssetType getType() override
{
return SceneAsset::SceneAssetType::Gltf;
}
bool isInstance() override
{
return false;
}
utils::Entity getEntity() override
{
return _asset->getRoot();
}
MaterialInstance **getMaterialInstances() override
{
return _materialInstances;
}
size_t getMaterialInstanceCount() override
{
return _materialInstanceCount;
}
gltfio::FilamentAsset *getAsset()
{
return _asset;
}
void addAllEntities(Scene *scene) override
{
scene->addEntities(_asset->getEntities(), _asset->getEntityCount());
scene->addEntities(_asset->getLightEntities(), _asset->getLightEntityCount());
scene->addEntities(_asset->getCameraEntities(), _asset->getCameraEntityCount());
}
void removeAllEntities(Scene *scene) override
{
scene->removeEntities(_asset->getEntities(), _asset->getEntityCount());
scene->removeEntities(_asset->getLightEntities(), _asset->getLightEntityCount());
scene->removeEntities(_asset->getCameraEntities(), _asset->getCameraEntityCount());
}
void setPriority(RenderableManager &rm, int priority) override
{
const Entity *entities = _asset->getEntities();
for (int i = 0; i < _asset->getEntityCount(); i++)
{
if (rm.hasComponent(entities[i]))
{
auto renderableInstance = rm.getInstance(entities[i]);
rm.setPriority(renderableInstance, priority);
}
}
}
void setLayer(RenderableManager &rm, int layer) override
{
const Entity *entities = _asset->getEntities();
for (int i = 0; i < _asset->getEntityCount(); i++)
{
if (rm.hasComponent(entities[i]))
{
auto renderableInstance = rm.getInstance(entities[i]);
rm.setLayerMask(renderableInstance, 0xFF, 1u << (uint8_t)layer);
}
}
}
SceneAsset *getInstanceByEntity(utils::Entity entity) override
{
for (auto &instance : _instances)
{
if (instance->getEntity() == entity)
{
return instance.get();
}
}
return std::nullptr_t();
}
SceneAsset *getInstanceAt(size_t index) override
{
auto &asset = _instances[index];
return asset.get();
}
size_t getInstanceCount() override
{
return _instances.size();
}
size_t getChildEntityCount() override
{
return _asset->getEntityCount();
}
const Entity* getChildEntities() override {
return _asset->getEntities();
}
Entity findEntityByName(const char* name) override {
Entity entities[1];
auto found = _asset->getEntitiesByName(name, entities, 1);
return entities[0];
}
private:
gltfio::FilamentAsset *_asset;
gltfio::AssetLoader *_assetLoader;
Engine *_engine;
MaterialInstance **_materialInstances = nullptr;
size_t _materialInstanceCount = 0;
std::vector<std::unique_ptr<GltfSceneAssetInstance>> _instances;
};
} // namespace thermion

View File

@@ -0,0 +1,143 @@
#pragma once
#include <memory>
#include <vector>
#include <filament/Engine.h>
#include <filament/RenderableManager.h>
#include <filament/VertexBuffer.h>
#include <filament/IndexBuffer.h>
#include <gltfio/FilamentAsset.h>
#include <gltfio/FilamentInstance.h>
#include <gltfio/MaterialProvider.h>
#include "scene/SceneAsset.hpp"
namespace thermion
{
using namespace filament;
class GltfSceneAssetInstance : public SceneAsset
{
public:
GltfSceneAssetInstance(
gltfio::FilamentInstance *instance,
Engine *engine,
MaterialInstance **materialInstances = nullptr,
size_t materialInstanceCount = 0,
int instanceIndex = -1) : _instance(instance),
_materialInstances(materialInstances),
_materialInstanceCount(materialInstanceCount)
{
}
~GltfSceneAssetInstance();
SceneAsset *createInstance(MaterialInstance **materialInstances = nullptr, size_t materialInstanceCount = 0) override
{
return std::nullptr_t();
};
SceneAssetType getType() override
{
return SceneAsset::SceneAssetType::Gltf;
}
bool isInstance() override
{
return true;
}
utils::Entity getEntity() override
{
return _instance->getRoot();
}
MaterialInstance **getMaterialInstances() override
{
return _materialInstances;
}
size_t getMaterialInstanceCount() override
{
return _materialInstanceCount;
}
gltfio::FilamentInstance *getInstance()
{
return _instance;
}
void addAllEntities(Scene *scene) override
{
scene->addEntities(_instance->getEntities(), _instance->getEntityCount());
}
void removeAllEntities(Scene *scene) override {
scene->removeEntities(_instance->getEntities(), _instance->getEntityCount());
}
size_t getInstanceCount() override
{
return 0;
}
SceneAsset *getInstanceAt(size_t index) override
{
return std::nullptr_t();
}
size_t getChildEntityCount() override
{
return _instance->getEntityCount();
}
const Entity* getChildEntities() override {
return _instance->getEntities();
}
Entity findEntityByName(const char* name) override {
return Entity(); // not currently implemented
}
SceneAsset *getInstanceByEntity(utils::Entity entity) override {
return std::nullptr_t();
}
void setPriority(RenderableManager &rm, int priority) override
{
const Entity *entities = _instance->getEntities();
for (int i = 0; i < _instance->getEntityCount(); i++)
{
if (rm.hasComponent(entities[i]))
{
auto renderableInstance = rm.getInstance(entities[i]);
rm.setPriority(renderableInstance, priority);
}
}
}
void setLayer(RenderableManager &rm, int layer) override
{
const Entity *entities = _instance->getEntities();
for (int i = 0; i < _instance->getEntityCount(); i++)
{
if (rm.hasComponent(entities[i]))
{
auto renderableInstance = rm.getInstance(entities[i]);
rm.setLayerMask(renderableInstance, 0xFF, 1u << (uint8_t)layer);
}
}
}
private:
filament::Engine *_engine;
gltfio::FilamentInstance *_instance;
MaterialInstance **_materialInstances = nullptr;
size_t _materialInstanceCount = 0;
};
} // namespace thermion

View File

@@ -0,0 +1,53 @@
#pragma once
#include <memory>
#include <utils/Entity.h>
#include <gltfio/FilamentAsset.h>
#include <filament/Scene.h>
#include "CustomGeometry.hpp"
#include "Log.hpp"
namespace thermion {
using namespace filament;
using namespace utils;
class SceneAsset {
public:
enum SceneAssetType { Gltf, Geometry, Light, Skybox, Ibl, Image, Gizmo };
virtual ~SceneAsset() {
}
virtual SceneAssetType getType() = 0;
virtual utils::Entity getEntity() {
return utils::Entity::import(0);
}
virtual bool isInstance() = 0;
virtual SceneAsset* createInstance(MaterialInstance **materialInstances, size_t materialInstanceCount) = 0;
virtual MaterialInstance **getMaterialInstances() = 0;
virtual size_t getMaterialInstanceCount() = 0;
virtual void addAllEntities(Scene *scene) = 0;
virtual void removeAllEntities(Scene *scene) = 0;
virtual size_t getInstanceCount() = 0;
virtual SceneAsset *getInstanceByEntity(utils::Entity entity) = 0;
virtual SceneAsset *getInstanceAt(size_t index) = 0;
virtual size_t getChildEntityCount() = 0;
virtual const Entity* getChildEntities() = 0;
virtual Entity findEntityByName(const char* name) = 0;
virtual void setPriority(RenderableManager& rm, int mask) = 0;
virtual void setLayer(RenderableManager& rm, int layer) = 0;
};
}

View File

@@ -0,0 +1,350 @@
#pragma once
#include <mutex>
#include <vector>
#include <memory>
#include <map>
#include <set>
#include <filament/Scene.h>
#include <filament/Camera.h>
#include <filament/View.h>
#include <gltfio/AssetLoader.h>
#include <gltfio/FilamentAsset.h>
#include <gltfio/FilamentInstance.h>
#include <gltfio/ResourceLoader.h>
#include <filament/IndexBuffer.h>
#include <filament/InstanceBuffer.h>
#include <utils/NameComponentManager.h>
#include "tsl/robin_map.h"
#include "AnimationManager.hpp"
#include "CustomGeometry.hpp"
#include "Gizmo.hpp"
#include "GridOverlay.hpp"
#include "ResourceBuffer.hpp"
#include "SceneAsset.hpp"
#include "components/CollisionComponentManager.hpp"
namespace thermion
{
typedef int32_t EntityId;
using namespace filament;
using namespace filament::gltfio;
using namespace utils;
using std::string;
using std::unique_ptr;
using std::vector;
class SceneManager
{
public:
SceneManager(
const ResourceLoaderWrapperImpl *const loader,
Engine *engine,
Scene *scene,
const char *uberArchivePath,
Camera *mainCamera);
~SceneManager();
enum LAYERS
{
DEFAULT_ASSETS = 0,
BACKGROUND = 6,
OVERLAY = 7,
};
////
/// @brief Load the glTF file from the specified path and adds all entities to the scene.
/// @param uri the path to the asset. Should be either asset:// (representing a Flutter asset), or file:// (representing a filesystem file).
/// @param relativeResourcePath the (relative) path to the asset's resources.
/// @return the glTF entity.
///
SceneAsset* loadGltf(const char *uri, const char *relativeResourcePath, int numInstances = 1, bool keepData = false);
////
/// @brief Load the GLB from the specified path, optionally creating multiple instances.
/// @param uri the path to the asset. Should be either asset:// (representing a Flutter asset), or file:// (representing a filesystem file).
/// @param numInstances the number of instances to create. Must be at least 1.
/// @return an Entity representing the FilamentAsset associated with the loaded FilamentAsset.
///
SceneAsset* loadGlb(const char *uri, int numInstances, bool keepData);
/// @brief
/// @param data
/// @param length
/// @param numInstances
/// @param keepData
/// @param priority
/// @param layer
/// @param loadResourcesAsync
/// @return
SceneAsset* loadGlbFromBuffer(const uint8_t *data, size_t length, int numInstances = 1, bool keepData = false, int priority = 4, int layer = 0, bool loadResourcesAsync = false);
///
/// Creates an instance of the given entity.
/// This may return an instance from a pool of inactive instances; see [remove] for more information.
/// If [materialInstances] is provided, these wil
///
SceneAsset* createInstance(SceneAsset* asset, MaterialInstance **materialInstances = nullptr, size_t materialInstanceCount = 0);
/// @brief Removes the asset (and all its child entities) from the scene and "destroys" all resources.
/// If the asset is not an instance, the asset will be deleted.
/// If the asset is an instance, [remove] is not guaranted to delete the asset. It may be returned to a pool of inactive instances.
/// From the user's perspective, this can be considered as destroyed.
/// @param entity
void destroy(SceneAsset* entity);
/// @brief Destroys all assets, scenes, materials, etc.
///
void destroyAll();
/// @brief
/// @param entityId
void transformToUnitCube(EntityId entityId);
/// @brief
/// @param entities
/// @param transforms
/// @param numEntities
void queueTransformUpdates(EntityId *entities, math::mat4 *transforms, int numEntities);
/// @brief
/// @param entity
/// @param viewportCoordX
/// @param viewportCoordY
/// @param x
/// @param y
/// @param z
void queueRelativePositionUpdateWorldAxis(EntityId entity, float viewportCoordX, float viewportCoordY, float x, float y, float z);
/// @brief
/// @param view
/// @param entityId
/// @param viewportCoordX
/// @param viewportCoordY
void queueRelativePositionUpdateFromViewportVector(View *view, EntityId entityId, float viewportCoordX, float viewportCoordY);
const utils::Entity *getCameraEntities(EntityId e);
size_t getCameraEntityCount(EntityId e);
const utils::Entity *getLightEntities(EntityId e) noexcept;
size_t getLightEntityCount(EntityId e) noexcept;
/// @brief
void update();
/// @brief
/// @param data
/// @param length
/// @param name
/// @return
Texture *createTexture(const uint8_t *data, size_t length, const char *name);
/// @brief
/// @param entityId
/// @param texture
/// @param slotName
/// @param materialIndex
/// @return
bool applyTexture(EntityId entityId, Texture *texture, const char *slotName, int materialIndex);
/// @brief
/// @param texture
void destroyTexture(Texture *texture);
/// @brief
/// @param entity
/// @return
bool removeFromScene(EntityId entity);
/// @brief
/// @param entity
/// @return
bool addToScene(EntityId entity);
/// @brief
/// @param entity
/// @param onCollisionCallback
/// @param affectsCollidingTransform
void addCollisionComponent(EntityId entity, void (*onCollisionCallback)(const EntityId entityId1, const EntityId entityId2), bool affectsCollidingTransform);
/// @brief
/// @param entityId
///
///
void removeCollisionComponent(EntityId entityId);
/// @brief
/// @param entity
void testCollisions(EntityId entity);
/// @brief returns the number of instances of the FilamentAsset represented by the given entity.
/// @param entityId
/// @return the number of instances
int getInstanceCount(EntityId entityId);
/// @brief returns an array containing all instances of the FilamentAsset represented by the given entity.
/// @param entityId
void getInstances(EntityId entityId, EntityId *out);
///
/// Sets the draw priority for the given entity. See RenderableManager.h for more details.
///
void setPriority(EntityId entity, int priority);
/// @brief returns the 2D min/max viewport coordinates of the bounding box for the specified enitty;
/// @param out a pointer large enough to store four floats (the min/max coordinates of the bounding box)
/// @return
///
Aabb2 getScreenSpaceBoundingBox(View *view, EntityId entity);
/// @brief returns the 3D bounding box of the renderable instance for the given entity.
/// @return the bounding box
///
Aabb3 getRenderableBoundingBox(EntityId entity);
///
/// Creates an entity with the specified geometry/material/normals and adds to the scene.
/// If [keepData] is true, stores
///
SceneAsset *createGeometry(
float *vertices,
uint32_t numVertices,
float *normals,
uint32_t numNormals,
float *uvs,
uint32_t numUvs,
uint16_t *indices,
uint32_t numIndices,
filament::RenderableManager::PrimitiveType primitiveType = RenderableManager::PrimitiveType::TRIANGLES,
MaterialInstance **materialInstances = nullptr,
size_t materialInstanceCount = 0,
bool keepData = false);
gltfio::MaterialProvider *const getUnlitMaterialProvider()
{
return _unlitMaterialProvider;
}
gltfio::MaterialProvider *const getUbershaderMaterialProvider()
{
return _ubershaderProvider;
}
/// @brief
/// @param materialInstance
void destroy(MaterialInstance *materialInstance);
/// @brief
/// @return
MaterialInstance *createUnlitFixedSizeMaterialInstance();
/// @brief
/// @return
MaterialInstance *createUnlitMaterialInstance();
/// @brief
/// @param entityId
/// @param layer
void setVisibilityLayer(EntityId entityId, int layer);
/// @brief
/// @return
Camera *createCamera();
/// @brief
/// @param camera
void destroyCamera(Camera *camera);
/// @brief
/// @return
size_t getCameraCount();
/// @brief
/// @param index
/// @return
Camera *getCameraAt(size_t index);
/// @brief
/// @param view
/// @param scene
/// @return
Gizmo *createGizmo(View *view, Scene *scene);
/// @brief
/// @return
Scene *getScene()
{
return _scene;
}
/// @brief
/// @return
AnimationManager *getAnimationManager() {
return _animationManager.get();
}
/// @brief
/// @return
NameComponentManager *getNameComponentManager() {
return _ncm;
}
Entity getOverlayEntity(size_t index) {
if(index == 0) {
return _gridOverlay->grid();
} else if(index == 1) {
return _gridOverlay->sphere();
}
}
size_t getOverlayEntityCount() {
return 2;
}
private:
gltfio::AssetLoader *_assetLoader = nullptr;
const ResourceLoaderWrapperImpl *const _resourceLoaderWrapper;
Engine *_engine = nullptr;
Scene *_scene = nullptr;
Camera *_mainCamera;
gltfio::MaterialKey _defaultUnlitConfig;
gltfio::MaterialProvider *_ubershaderProvider = nullptr;
gltfio::MaterialProvider *_unlitMaterialProvider = nullptr;
gltfio::ResourceLoader *_gltfResourceLoader = nullptr;
gltfio::TextureProvider *_stbDecoder = nullptr;
gltfio::TextureProvider *_ktxDecoder = nullptr;
std::mutex _mutex;
std::vector<MaterialInstance *> _materialInstances;
Material *_unlitFixedSizeMaterial = nullptr;
utils::NameComponentManager *_ncm;
tsl::robin_map<EntityId, math::mat4> _transformUpdates;
std::set<Texture *> _textures;
std::vector<Camera *> _cameras;
std::vector<std::unique_ptr<SceneAsset>> _sceneAssets;
std::vector<std::unique_ptr<Gizmo>> _gizmos;
std::unique_ptr<AnimationManager> _animationManager = std::nullptr_t();
std::unique_ptr<CollisionComponentManager> _collisionComponentManager = std::nullptr_t();
GridOverlay *_gridOverlay = std::nullptr_t();
void _updateTransforms();
};
}