Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: <ModelInstance /> component #219

Merged
merged 5 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package/cpp/bullet/RNFShapeWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace margelo {
*/
class ShapeWrapper : public HybridObject {
public:
explicit ShapeWrapper(const char* name, std::shared_ptr<btCollisionShape> shape) : HybridObject(name), _shape(shape){};
explicit ShapeWrapper(const char* name, std::shared_ptr<btCollisionShape> shape) : HybridObject(name), _shape(shape) {};

void loadHybridMethods() override;

Expand Down
4 changes: 4 additions & 0 deletions package/cpp/core/RNFAABBWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ class AABBWrapper : public HybridObject {
explicit AABBWrapper(const Aabb& aabb) : HybridObject("AABBWrapper"), _aabb(aabb) {}
void loadHybridMethods() override;

Aabb getAabb() {
return _aabb;
}

private: // Exposed JS api
std::vector<double> getCenter();
std::vector<double> getHalfExtent();
Expand Down
2 changes: 1 addition & 1 deletion package/cpp/core/RNFFilamentAssetWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ void FilamentAssetWrapper::loadHybridMethods() {
registerHybridMethod("getEntities", &FilamentAssetWrapper::getEntities, this);
registerHybridGetter("renderableEntityCount", &FilamentAssetWrapper::getRenderableEntityCount, this);
registerHybridMethod("getRenderableEntities", &FilamentAssetWrapper::getRenderableEntities, this);
registerHybridGetter("boundingBox", &FilamentAssetWrapper::getBoundingBox, this);
registerHybridMethod("getBoundingBox", &FilamentAssetWrapper::getBoundingBox, this);
registerHybridMethod("getFirstEntityByName", &FilamentAssetWrapper::getFirstEntityByName, this);
registerHybridMethod("getInstance", &FilamentAssetWrapper::getInstance, this);
registerHybridMethod("getAssetInstances", &FilamentAssetWrapper::getAssetInstances, this);
Expand Down
6 changes: 6 additions & 0 deletions package/cpp/core/RNFFilamentInstanceWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,18 @@
namespace margelo {

void FilamentInstanceWrapper::loadHybridMethods() {
registerHybridGetter("entityCount", &FilamentInstanceWrapper::getEntityCount, this);
registerHybridMethod("getEntities", &FilamentInstanceWrapper::getEntities, this);
registerHybridMethod("getRoot", &FilamentInstanceWrapper::getRoot, this);
registerHybridMethod("createAnimator", &FilamentInstanceWrapper::createAnimator, this);
registerHybridMethod("getBoundingBox", &FilamentInstanceWrapper::getBoundingBox, this);
}

int FilamentInstanceWrapper::getEntityCount() {
size_t count = _instance->getEntityCount();
return static_cast<int>(count);
}

std::vector<std::shared_ptr<EntityWrapper>> FilamentInstanceWrapper::getEntities() {
std::vector<std::shared_ptr<EntityWrapper>> entities;
const Entity* entityArray = _instance->getEntities();
Expand Down
1 change: 1 addition & 0 deletions package/cpp/core/RNFFilamentInstanceWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class FilamentInstanceWrapper : public HybridObject {
}

private: // Public JS API
int getEntityCount();
std::vector<std::shared_ptr<EntityWrapper>> getEntities();
std::shared_ptr<EntityWrapper> getRoot();
/**
Expand Down
2 changes: 1 addition & 1 deletion package/cpp/core/RNFNameComponentManagerWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class NameComponentManagerWrapper : public PointerHolder<NameComponentManager> {
explicit NameComponentManagerWrapper(std::shared_ptr<NameComponentManager> nameComponentManager)
: PointerHolder(TAG, nameComponentManager) {}

void loadHybridMethods() override{};
void loadHybridMethods() override {};

std::shared_ptr<NameComponentManager> getManager() {
return pointee();
Expand Down
35 changes: 35 additions & 0 deletions package/cpp/core/RNFSceneWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ namespace margelo {

void margelo::SceneWrapper::loadHybridMethods() {
registerHybridMethod("addEntity", &SceneWrapper::addEntity, this);
registerHybridMethod("addEntities", &SceneWrapper::addEntities, this);
registerHybridMethod("removeEntity", &SceneWrapper::removeEntity, this);
registerHybridMethod("removeEntities", &SceneWrapper::removeEntities, this);
registerHybridMethod("addAssetEntities", &SceneWrapper::addAssetEntities, this);
registerHybridMethod("removeAssetEntities", &SceneWrapper::removeAssetEntities, this);
registerHybridGetter("entityCount", &SceneWrapper::getEntityCount, this);
Expand All @@ -22,6 +24,15 @@ void margelo::SceneWrapper::addEntity(std::shared_ptr<EntityWrapper> entity) {
pointee()->addEntity(entity->getEntity());
}

void SceneWrapper::addEntities(std::vector<std::shared_ptr<EntityWrapper>> entities) {
std::unique_lock lock(_mutex);

size_t count = entities.size();
std::vector<Entity> entityArray = entityWrapperVectorToEntityVector(entities, count);
const Entity* entityArrayPtr = entityArray.data();
pointee()->addEntities(entityArrayPtr, count);
}

void SceneWrapper::removeEntity(std::shared_ptr<EntityWrapper> entity) {
std::unique_lock lock(_mutex);

Expand All @@ -32,6 +43,15 @@ void SceneWrapper::removeEntity(std::shared_ptr<EntityWrapper> entity) {
pointee()->remove(entity->getEntity());
}

void SceneWrapper::removeEntities(std::vector<std::shared_ptr<EntityWrapper>> entities) {
std::unique_lock lock(_mutex);

size_t count = entities.size();
std::vector<Entity> entityArray = entityWrapperVectorToEntityVector(entities, count);
const Entity* entityArrayPtr = entityArray.data();
pointee()->removeEntities(entityArrayPtr, count);
}

void SceneWrapper::addAsset(std::shared_ptr<gltfio::FilamentAsset> asset) {
std::unique_lock lock(_mutex);

Expand Down Expand Up @@ -87,4 +107,19 @@ int SceneWrapper::getEntityCount() {
return pointee()->getEntityCount();
}

std::vector<Entity> SceneWrapper::entityWrapperVectorToEntityVector(std::vector<std::shared_ptr<EntityWrapper>> entities, size_t count) {
if (entities.empty()) {
throw std::invalid_argument("Entities are empty");
}

std::vector<Entity> entityArray;
entityArray.reserve(count);
for (const auto& entityWrapper : entities) {
Entity entity = entityWrapper->getEntity();
entityArray.push_back(entity);
}

return entityArray;
}

} // namespace margelo
5 changes: 5 additions & 0 deletions package/cpp/core/RNFSceneWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ class SceneWrapper : public PointerHolder<Scene> {

private: // Public JS API
void addEntity(std::shared_ptr<EntityWrapper> entity);
void addEntities(std::vector<std::shared_ptr<EntityWrapper>> entities);
void removeEntity(std::shared_ptr<EntityWrapper> entity);
void removeEntities(std::vector<std::shared_ptr<EntityWrapper>> entities);
/**
* Removed all entities associated with the provided asset from the scene.
*/
Expand All @@ -37,5 +39,8 @@ class SceneWrapper : public PointerHolder<Scene> {
void addAssetEntities(std::shared_ptr<FilamentAssetWrapper> asset);

int getEntityCount();

private: // Internal
std::vector<Entity> entityWrapperVectorToEntityVector(std::vector<std::shared_ptr<EntityWrapper>> entities, size_t count);
};
} // namespace margelo
7 changes: 3 additions & 4 deletions package/cpp/core/RNFTransformManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//

#include "RNFTransformManagerImpl.h"
#include "RNFAABBWrapper.h"
#include "core/utils/RNFConverter.h"
#include <filament/TransformManager.h>
#include <math/mat4.h>
Expand Down Expand Up @@ -133,19 +134,17 @@ void TransformManagerImpl::updateTransformByRigidBody(Entity entity, std::shared
}

/**
* Sets up a root transform on the current model to make it fit into a unit cube.
* Sets up a root transform on the root to make it fit into a cube of the size of 1 unit.
*/
void TransformManagerImpl::transformToUnitCube(std::shared_ptr<gltfio::FilamentAsset> asset) {
void TransformManagerImpl::transformToUnitCube(Entity rootEntity, Aabb aabb) {
std::unique_lock lock(_mutex);
TransformManager& transformManager = _engine->getTransformManager();
Aabb aabb = asset->getBoundingBox();
math::details::TVec3<float> center = aabb.center();
math::details::TVec3<float> halfExtent = aabb.extent();
float maxExtent = max(halfExtent) * 2.0f;
float scaleFactor = 2.0f / maxExtent;
math::mat4f transform = math::mat4f::scaling(scaleFactor) * math::mat4f::translation(-center);

Entity rootEntity = asset->getRoot();
TransformManager::Instance instance = getInstance(rootEntity, transformManager);
transformManager.setTransform(instance, transform);
}
Expand Down
2 changes: 1 addition & 1 deletion package/cpp/core/RNFTransformManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class TransformManagerImpl {
void setEntityRotation(Entity entity, double angleRadians, std::vector<double> axisVec, bool multiplyCurrent);
void setEntityScale(Entity entity, std::vector<double> scaleVec, bool multiplyCurrent);
void updateTransformByRigidBody(Entity entity, std::shared_ptr<RigidBodyWrapper> rigidBody);
void transformToUnitCube(std::shared_ptr<gltfio::FilamentAsset> asset);
void transformToUnitCube(Entity rootEntity, Aabb aabb);

private: // Internal
void updateTransform(math::mat4 transform, Entity entity, bool multiplyCurrent);
Expand Down
14 changes: 11 additions & 3 deletions package/cpp/core/RNFTransformManagerWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,17 @@ void TransformManagerWrapper::updateTransformByRigidBody(std::shared_ptr<EntityW
Entity entity = getEntity(entityWrapper);
pointee()->updateTransformByRigidBody(entity, rigidBody);
}
void TransformManagerWrapper::transformToUnitCube(std::shared_ptr<FilamentAssetWrapper> assetWrapper) {
std::shared_ptr<gltfio::FilamentAsset> asset = assetWrapper->getAsset();
pointee()->transformToUnitCube(asset);
void TransformManagerWrapper::transformToUnitCube(std::shared_ptr<EntityWrapper> rootEntityWrapper,
std::shared_ptr<AABBWrapper> aabbWrapper) {
if (!aabbWrapper) {
[[unlikely]];
throw std::invalid_argument("AABB is null");
}

Aabb aabb = aabbWrapper->getAabb();
Entity rootEntity = getEntity(rootEntityWrapper);

pointee()->transformToUnitCube(rootEntity, aabb);
}

Entity TransformManagerWrapper::getEntity(std::shared_ptr<EntityWrapper> entityWrapper) {
Expand Down
2 changes: 1 addition & 1 deletion package/cpp/core/RNFTransformManagerWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class TransformManagerWrapper : public PointerHolder<TransformManagerImpl> {
void setEntityRotation(std::shared_ptr<EntityWrapper> entity, double angleRadians, std::vector<double> axisVec, bool multiplyCurrent);
void setEntityScale(std::shared_ptr<EntityWrapper> entity, std::vector<double> scaleVec, bool multiplyCurrent);
void updateTransformByRigidBody(std::shared_ptr<EntityWrapper> entityWrapper, std::shared_ptr<RigidBodyWrapper> rigidBody);
void transformToUnitCube(std::shared_ptr<FilamentAssetWrapper> assetWrapper);
void transformToUnitCube(std::shared_ptr<EntityWrapper> rootEntityWrapper, std::shared_ptr<AABBWrapper> aabbWrapper);

private: // Internal
Entity getEntity(std::shared_ptr<EntityWrapper> entityWrapper);
Expand Down
10 changes: 6 additions & 4 deletions package/example/Shared/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ console.log(`Using react-native-worklets-core@${version}`)
import { setLogger } from 'react-native-filament'
// A function that can wrap a console log call to add a prefix
const prefix = '[filament-logger]'
const prefixLog = (logFn) => (...messages) => {
const date = new Date()
logFn(prefix, `[${date.toLocaleTimeString()} ${date.getMilliseconds().toString().padStart(3, 0)}]`, ...messages)
}
const prefixLog =
(logFn) =>
(...messages) => {
const date = new Date()
logFn(prefix, `[${date.toLocaleTimeString()} ${date.getMilliseconds().toString().padStart(3, 0)}]`, ...messages)
}
setLogger({
debug: prefixLog(console.debug),
log: prefixLog(console.log),
Expand Down
2 changes: 1 addition & 1 deletion package/example/Shared/src/AnimationTransitions.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useNavigation } from '@react-navigation/native'
import * as React from 'react'
import { Alert, Button, ScrollView, StyleSheet, View } from 'react-native'
import { FilamentContext, FilamentView, Camera, Model, Animator, AnimationItem, Entity, DefaultLight, Group } from 'react-native-filament'
import { FilamentContext, FilamentView, Camera, Model, Animator, AnimationItem, Entity, DefaultLight } from 'react-native-filament'
import { useSharedValue } from 'react-native-worklets-core'
import HipHopGirlGlb from '~/assets/hiphopgirl.glb'
import { SafeAreaView } from 'react-native-safe-area-context'
Expand Down
6 changes: 3 additions & 3 deletions package/example/Shared/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import { AnimationTransitionsRecording } from './AnimationTransitionsRecording'
import { ImageExample } from './ImageExample'
import { LoadFromFile } from './LoadFromFile'
import { NoneTransparent } from './NoneTransparent'
import { MultipleInstances } from './MultipleInstances'
// import { ChangeMaterials } from './ChangeMaterials'
// import { PhysicsCoin } from './PhysicsCoin'
// import { FadeOut } from './FadeOut'
// import { CastShadow } from './CastShadow'
// import { MultipleInstances } from './MultipleInstances'
// import { WorkletExample } from './WorkletExample'
// import { ScaleEffect } from './ScaleEffect'
// import { FadingLightExample } from './FadingLightExample'
Expand Down Expand Up @@ -55,9 +55,9 @@ function HomeScreen() {
<NavigationItem name="🏞️ Image" route="ImageExample" />
<NavigationItem name="📦 Load from file" route="LoadFromFile" />
<NavigationItem name="🫥 None Transparent rendering" route="NoneTransparent" />
<NavigationItem name="🤖 Multiple Instances" route="MultipleInstances" />
{/* <NavigationItem name="💰 Physics Coin" route="PhysicsCoin" />
<NavigationItem name="🌑 Cast Shadow" route="CastShadow" />
<NavigationItem name="🤖 Multiple Instances" route="MultipleInstances" />
<NavigationItem name="😶‍🌫️ Fade Out" route="FadeOut" />
<NavigationItem name="↕️ Scale Effect" route="ScaleEffect" /> */}
</ScrollView>
Expand Down Expand Up @@ -92,13 +92,13 @@ function App() {
<Stack.Screen name="ImageExample" component={ImageExample} />
<Stack.Screen name="LoadFromFile" component={LoadFromFile} />
<Stack.Screen name="NoneTransparent" component={NoneTransparent} />
<Stack.Screen name="MultipleInstances" component={MultipleInstances} />
{/* TODO: Migrate */}
{/* <Stack.Screen name="ChangeMaterials" component={ChangeMaterials} />
<Stack.Screen name="PhysicsCoin" component={PhysicsCoin} />
<Stack.Screen name="FadeOut" component={FadeOut} />
<Stack.Screen name="ChangeMaterials" component={ChangeGoldenMaterials} />
<Stack.Screen name="CastShadow" component={CastShadow} />
<Stack.Screen name="MultipleInstances" component={MultipleInstances} />
<Stack.Screen name="WorkletExample" component={WorkletExample} />
<Stack.Screen name="ScaleEffect" component={ScaleEffect} />
<Stack.Screen name="FadingLight" component={FadingLightExample} /> */}
Expand Down
Loading