From 555d1199a2b04f1df3fea6fec9b33df0c1df3e48 Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Thu, 22 Jun 2023 13:38:17 +0800 Subject: [PATCH] add implementation for setMorphWeights --- ios/include/AssetManager.hpp | 2 + ios/include/FilamentViewer.hpp | 8 +- ios/include/PolyvoxFilamentApi.h | 8 ++ ios/include/ThreadPool.hpp | 2 +- ios/src/AssetManager.cpp | 31 +++- ios/src/FilamentViewer.cpp | 233 +++++++++++-------------------- ios/src/PolyvoxFilamentApi.cpp | 20 +++ lib/filament_controller.dart | 23 ++- lib/generated_bindings.dart | 33 ++++- 9 files changed, 196 insertions(+), 164 deletions(-) diff --git a/ios/include/AssetManager.hpp b/ios/include/AssetManager.hpp index 84b8a35b..9b7f7fa4 100644 --- a/ios/include/AssetManager.hpp +++ b/ios/include/AssetManager.hpp @@ -55,6 +55,8 @@ namespace polyvox { int numMorphWeights, int numFrames, float frameLengthInMs); + void setMorphTargetWeights(EntityId entityId, const char* const entityName, const float* const weights, int count); + void playAnimation(EntityId e, int index, bool loop, bool reverse); void stopAnimation(EntityId e, int index); void setMorphTargetWeights(const char* const entityName, float *weights, int count); diff --git a/ios/include/FilamentViewer.hpp b/ios/include/FilamentViewer.hpp index 0306f2f9..467cda2a 100644 --- a/ios/include/FilamentViewer.hpp +++ b/ios/include/FilamentViewer.hpp @@ -100,9 +100,11 @@ namespace polyvox { private: void createImageRenderable(); void loadResources(std::string relativeResourcePath); - void cleanup(); - - Manipulator* _manipulator = nullptr; + void cleanup(); + + bool _panning = false; + float _startX; + float _startY; math::mat4f _cameraPosition; math::mat4f _cameraRotation; diff --git a/ios/include/PolyvoxFilamentApi.h b/ios/include/PolyvoxFilamentApi.h index 01eae3e6..d3ee3515 100644 --- a/ios/include/PolyvoxFilamentApi.h +++ b/ios/include/PolyvoxFilamentApi.h @@ -48,6 +48,14 @@ void apply_weights( int count ); +void set_morph_target_weights( + void* assetManager, + EntityId asset, + const char *const entityName, + const float *const morphData, + int numWeights +); + bool set_morph_animation( void* assetManager, EntityId asset, diff --git a/ios/include/ThreadPool.hpp b/ios/include/ThreadPool.hpp index be79ad7b..9a8a6f38 100644 --- a/ios/include/ThreadPool.hpp +++ b/ios/include/ThreadPool.hpp @@ -44,7 +44,7 @@ public: std::unique_lock lock(access); auto ret = pt.get_future(); - tasks.push_back([pt=std::make_shared>(std::move(pt))]{ (*pt)();}); + tasks.push_back([pt=std::make_shared>(std::move(pt))]{ (*pt)();}); cond.notify_one(); diff --git a/ios/src/AssetManager.cpp b/ios/src/AssetManager.cpp index 80995664..597cd7b7 100644 --- a/ios/src/AssetManager.cpp +++ b/ios/src/AssetManager.cpp @@ -316,7 +316,11 @@ void AssetManager::updateAnimations() { } } if(asset.mAnimating) { - asset.mAnimator->updateBoneMatrices(); + if(!asset.mAnimator) { + Log("WARNING"); + } else { + asset.mAnimator->updateBoneMatrices(); + } } } } @@ -345,8 +349,29 @@ void AssetManager::remove(EntityId entityId) { sceneAsset.mAsset = nullptr; // still need to remove this somewhere... } -void AssetManager::setMorphTargetWeights(const char* const entityName, float *weights, int count) { - // TODO +void AssetManager::setMorphTargetWeights(EntityId entityId, const char* const entityName, const float* const weights, const int count) { + const auto& pos = _entityIdLookup.find(entityId); + if(pos == _entityIdLookup.end()) { + Log("ERROR: asset not found for entity."); + return; + } + auto& asset = _assets[pos->second]; + + auto entity = findEntityByName(asset, entityName); + if(!entity) { + Log("Warning: failed to find entity %s", entityName); + return; + } + + RenderableManager &rm = _engine->getRenderableManager(); + + rm.setMorphWeights( + rm.getInstance(entity), + weights, + count + ); + + } utils::Entity AssetManager::findEntityByName(SceneAsset asset, const char* entityName) { diff --git a/ios/src/FilamentViewer.cpp b/ios/src/FilamentViewer.cpp index 6fdab983..25dfe9e9 100644 --- a/ios/src/FilamentViewer.cpp +++ b/ios/src/FilamentViewer.cpp @@ -47,8 +47,6 @@ #include -#include - #include #include @@ -56,6 +54,8 @@ #include "math.h" #include +#include + #include #include #include @@ -137,17 +137,18 @@ FilamentViewer::FilamentViewer(void* context, ResourceLoaderWrapper* resourceLoa _view = _engine->createView(); decltype(_view->getBloomOptions()) opts; - opts.enabled = false; + opts.enabled = false;//true; + // opts.strength = 0.6f; _view->setBloomOptions(opts); _view->setScene(_scene); _view->setCamera(_mainCamera); - ToneMapper *tm = new LinearToneMapper(); - colorGrading = ColorGrading::Builder().toneMapper(tm).build(*_engine); - delete tm; + ToneMapper *tm = new LinearToneMapper(); + colorGrading = ColorGrading::Builder().toneMapper(tm).build(*_engine); + delete tm; - _view->setColorGrading(colorGrading); + _view->setColorGrading(colorGrading); _cameraFocalLength = 28.0f; _mainCamera->setLensProjection(_cameraFocalLength, 1.0f, kNearPlane, @@ -586,11 +587,6 @@ void FilamentViewer::clearAssets() { _view->setCamera(_mainCamera); } - if(_manipulator) { - delete _manipulator; - _manipulator = nullptr; - } - _assetManager->destroyAll(); Log("Cleared all assets"); @@ -641,52 +637,56 @@ void FilamentViewer::setCameraFocusDistance(float focusDistance) { /// bool FilamentViewer::setCamera(EntityId entityId, const char *cameraName) { - auto asset = _assetManager->getAssetByEntityId(entityId); - if(!asset) { - Log("Failed to find asset attached to specified entity id."); - } - size_t count = asset->getCameraEntityCount(); - if (count == 0) { - Log("Failed, no cameras found in current asset."); - return false; - } - - const utils::Entity* cameras = asset->getCameraEntities(); - - const utils::Entity target; - - int i = -1; - - if(!cameraName) { - i = 0; - } else { - for (int j = 0; j < count; j++) { - auto inst = _ncm->getInstance(cameras[j]); - const char *name = _ncm->getName(inst); - if (strcmp(name, cameraName) == 0) { - i = j; - break; - } + auto asset = _assetManager->getAssetByEntityId(entityId); + if(!asset) { + Log("Failed to find asset attached to specified entity id."); } - if(i == -1) { + size_t count = asset->getCameraEntityCount(); + if (count == 0) { + Log("Failed, no cameras found in current asset."); + return false; + } + + const utils::Entity* cameras = asset->getCameraEntities(); + + utils::Entity target; + + if(!cameraName) { + auto inst = _ncm->getInstance(cameras[0]); + const char *name = _ncm->getName(inst); + target = cameras[0]; + Log("No camera specified, using first : %s", name); + } else { + for (int j = 0; j < count; j++) { + auto inst = _ncm->getInstance(cameras[j]); + const char *name = _ncm->getName(inst); + if (strcmp(name, cameraName) == 0) { + target = cameras[j]; + break; + } + } + } + if(target.isNull()) { Log("Unable to locate camera under name %s ", cameraName); return false; } - } - Camera *camera = _engine->getCameraComponent(target); - _view->setCamera(camera); + Camera *camera = _engine->getCameraComponent(target); + if(!camera) { + Log("Failed to retrieve camera component for target"); + } + _view->setCamera(camera); - const Viewport &vp = _view->getViewport(); - const double aspect = (double)vp.width / vp.height; + const Viewport &vp = _view->getViewport(); + const double aspect = (double)vp.width / vp.height; - // const float aperture = camera->getAperture(); - // const float shutterSpeed = camera->getShutterSpeed(); - // const float sens = camera->getSensitivity(); - // camera->setExposure(1.0f); + // const float aperture = camera->getAperture(); + // const float shutterSpeed = camera->getShutterSpeed(); + // const float sens = camera->getSensitivity(); + // camera->setExposure(1.0f); - camera->setScaling({1.0 / aspect, 1.0}); - return true; + camera->setScaling({1.0 / aspect, 1.0}); + return true; } void FilamentViewer::loadSkybox(const char *const skyboxPath) { @@ -788,7 +788,7 @@ void FilamentViewer::render(uint64_t frameTimeInNanos) { } if(_frameCount == 60) { - Log("1 sec average for asset animation update %f", _elapsed); + //Log("1 sec average for asset animation update %f", _elapsed); _elapsed = 0; _frameCount = 0; } @@ -800,15 +800,6 @@ void FilamentViewer::render(uint64_t frameTimeInNanos) { _elapsed += tmr.elapsed(); _frameCount++; - if(_manipulator) { - math::float3 eye, target, upward; - Camera& cam =_view->getCamera(); - _manipulator->update((float(frameTimeInNanos) - float(_lastFrameTimeInNanos)) / 1000000); - _lastFrameTimeInNanos = frameTimeInNanos; - _manipulator->getLookAt(&eye, &target, &upward); - cam.lookAt(eye, target, upward); - } - // Render the scene, unless the renderer wants to skip the frame. if (_renderer->beginFrame(_swapChain, frameTimeInNanos)) { _renderer->render(_view); @@ -843,10 +834,6 @@ void FilamentViewer::updateViewportAndCameraProjection( } void FilamentViewer::setCameraPosition(float x, float y, float z) { - if(_manipulator) { - delete _manipulator; - _manipulator = nullptr; - } Camera& cam =_view->getCamera(); _cameraPosition = math::mat4f::translation(math::float3(x,y,z)); @@ -854,10 +841,6 @@ void FilamentViewer::setCameraPosition(float x, float y, float z) { } void FilamentViewer::setCameraRotation(float rads, float x, float y, float z) { - if(_manipulator) { - delete _manipulator; - _manipulator = nullptr; - } Camera& cam =_view->getCamera(); _cameraRotation = math::mat4f::rotation(rads, math::float3(x,y,z)); @@ -865,10 +848,6 @@ void FilamentViewer::setCameraRotation(float rads, float x, float y, float z) { } void FilamentViewer::setCameraModelMatrix(const float* const matrix) { - if(_manipulator) { - delete _manipulator; - _manipulator = nullptr; - } Camera& cam =_view->getCamera(); mat4 modelMatrix( @@ -892,48 +871,40 @@ void FilamentViewer::setCameraModelMatrix(const float* const matrix) { cam.setModelMatrix(modelMatrix); } -void FilamentViewer::_createManipulator() { - if(_manipulator) { - delete _manipulator; - } - Camera& cam =_view->getCamera(); - math::float3 home = cam.getPosition(); - math::float3 fv = cam.getForwardVector(); - math::float3 tp = home + fv; - Viewport const& vp = _view->getViewport(); - _manipulator = Manipulator::Builder() - .viewport(vp.width, vp.height) - .orbitHomePosition(home[0], home[1], home[2]) - .targetPosition(tp[0], tp[1], tp[2]) - .build(Mode::ORBIT); - _lastFrameTimeInNanos = 0; - // Log("Created orbit manipulator for vp width %d height %d with home %f %f %f and target pos %f %f %f ", vp.width, vp.height, home[0], home[1], home[2], tp[0], tp[1], tp[2]); -} - void FilamentViewer::grabBegin(float x, float y, bool pan) { if (!_view || !_mainCamera || !_swapChain) { Log("View not ready, ignoring grab"); return; } - if(!_manipulator) { - _createManipulator(); - } else { - Log("Error - calling grabBegin while another grab session is active. This will probably cause weirdness"); - return; - } - _manipulator->grabBegin(x, y, pan); + _panning = pan; + _startX = x; + _startY = y; } void FilamentViewer::grabUpdate(float x, float y) { - if (!_view || !_mainCamera || !_swapChain) { - Log("View not ready, ignoring grab"); - return; - } - if(_manipulator) { - _manipulator->grabUpdate(x, y); - } else { - Log("Error - trying to use a manipulator when one is not available. Ensure you call grabBegin before grabUpdate/grabEnd"); - } + if (!_view || !_swapChain) { + Log("View not ready, ignoring grab"); + return; + } + Camera& cam =_view->getCamera(); + auto eye = cam.getPosition();// math::float3 {0.0f, 0.5f, 50.0f } ;// ; // + auto target = eye + cam.getForwardVector(); + auto upward = cam.getUpVector(); + Viewport const& vp = _view->getViewport(); + if(_panning) { + auto trans = cam.getModelMatrix() * mat4::translation(math::float3 { 10 * (x - _startX) / vp.width, 10 * (y - _startY) / vp.height, 0.0f }); + cam.setModelMatrix(trans); + } else { + auto trans = cam.getModelMatrix() * mat4::rotation( + + 0.01, +// math::float3 { 0.0f, 1.0f, 0.0f }); + math::float3 { (y - _startY) / vp.height, (x - _startX) / vp.width, 0.0f }); + cam.setModelMatrix(trans); + } + _startX = x; + _startY = y; + } void FilamentViewer::grabEnd() { @@ -941,59 +912,21 @@ void FilamentViewer::grabEnd() { Log("View not ready, ignoring grab"); return; } - if(_manipulator) { - _manipulator->grabEnd(); - delete _manipulator; - _manipulator = nullptr; - Camera& cam =_view->getCamera(); - math::mat4 camMatrix = cam.getModelMatrix(); - // math::float3 home = cam.getPosition(); - // math::float3 fv = cam.getForwardVector(); - Log("Destroyed manipulator, end camera model matrix was %0.3f %0.3f %03.f %03.f %0.3f %0.3f %03.f %03.f %0.3f %0.3f %03.f %03.f %0.3f %0.3f %03.f %03.f ", - camMatrix[0][0], - camMatrix[0][1], - camMatrix[0][2], - camMatrix[0][3], - camMatrix[1][0], - camMatrix[1][1], - camMatrix[1][2], - camMatrix[1][3], - camMatrix[2][0], - camMatrix[2][1], - camMatrix[2][2], - camMatrix[2][3], - camMatrix[3][0], - camMatrix[3][1], - camMatrix[3][2], - camMatrix[3][3] - ); - } else { - Log("Error - trying to call GrabEnd when a manipulator is not available. Ensure you call grabBegin before grabUpdate/grabEnd"); - } } void FilamentViewer::scrollBegin() { - if(!_manipulator) { - _createManipulator(); - } + // noop } void FilamentViewer::scrollUpdate(float x, float y, float delta) { - if(!_manipulator) { - Log("No manipulator has been created - ensure you call scrollStart before scroll"); - return; - } - _manipulator->scroll(x, y, delta); + Camera& cam =_view->getCamera(); + Viewport const& vp = _view->getViewport(); + auto trans = cam.getModelMatrix() * mat4::translation(math::float3 {0.0f, 0.0f, delta }); + cam.setModelMatrix(trans); } void FilamentViewer::scrollEnd() { - if(!_manipulator) { - Log("No manipulator has been created - ensure you call scrollStart before scroll/scrollEnd"); - return; - } - delete _manipulator; - _manipulator = nullptr; - Log("Destroyed manipulator"); + } } // namespace polyvox diff --git a/ios/src/PolyvoxFilamentApi.cpp b/ios/src/PolyvoxFilamentApi.cpp index 265e4ca5..f1b1f760 100644 --- a/ios/src/PolyvoxFilamentApi.cpp +++ b/ios/src/PolyvoxFilamentApi.cpp @@ -332,6 +332,26 @@ extern "C" { // fut.wait(); } + FLUTTER_PLUGIN_EXPORT void set_morph_target_weights( + void* assetManager, + EntityId asset, + const char* const entityName, + const float* const weights, + const int numWeights + ) { + + //std::packaged_task lambda([=]() mutable { + return ((AssetManager*)assetManager)->setMorphTargetWeights( + asset, + entityName, + weights, + numWeights + ); + //}); +// auto fut = _tp->add_task(lambda); +// fut.wait(); + } + FLUTTER_PLUGIN_EXPORT bool set_morph_animation( void* assetManager, EntityId asset, diff --git a/lib/filament_controller.dart b/lib/filament_controller.dart index 1fa65cb7..18e71a86 100644 --- a/lib/filament_controller.dart +++ b/lib/filament_controller.dart @@ -264,9 +264,16 @@ class FilamentController { _nativeLibrary.grab_end(_viewer); } - void setMorphTargetWeights(FilamentEntity asset, List weights) { - throw Exception("TODO"); - // _nativeLibrary.set_morph_target_weights(_assetManager, asset, Float32List.fromList(weights)); + void setMorphTargetWeights( + FilamentEntity asset, String meshName, List weights) { + var weightPtr = calloc(weights.length); + for (int i = 0; i < weights.length; i++) { + weightPtr[i] = weights[i]; + } + + _nativeLibrary.set_morph_target_weights(_assetManager, asset, + meshName.toNativeUtf8().cast(), weightPtr, weights.length); + calloc.free(weightPtr); } List getMorphTargetNames(FilamentEntity asset, String meshName) { @@ -300,6 +307,7 @@ class FilamentController { /// Each frame is [numWeights] in length, and each entry is the weight to be applied to the morph target located at that index in the mesh primitive at that frame. /// void setMorphAnimation(FilamentEntity asset, MorphAnimation animation) async { + print("Setting morph animation"); var data = calloc(animation.data.length); for (int i = 0; i < animation.data.length; i++) { data.elementAt(i).value = animation.data[i]; @@ -393,8 +401,13 @@ class FilamentController { _nativeLibrary.stop_animation(_assetManager, asset, animationIndex); } - void setCamera(FilamentEntity asset, String name) async { - _nativeLibrary.set_camera(_viewer, asset, name.toNativeUtf8().cast()); + void setCamera(FilamentEntity asset, String? name) async { + if (_nativeLibrary.set_camera( + _viewer, asset, name?.toNativeUtf8()?.cast() ?? nullptr) != + 1) { + throw Exception("Failed to set camera"); + } + ; } void setCameraFocalLength(double focalLength) async { diff --git a/lib/generated_bindings.dart b/lib/generated_bindings.dart index fbba1e36..204b6d5c 100644 --- a/lib/generated_bindings.dart +++ b/lib/generated_bindings.dart @@ -618,6 +618,35 @@ class NativeLibrary { void Function(ffi.Pointer, int, ffi.Pointer, ffi.Pointer, int)>(); + void set_morph_target_weights( + ffi.Pointer assetManager, + int asset, + ffi.Pointer entityName, + ffi.Pointer morphData, + int numWeights, + ) { + return _set_morph_target_weights( + assetManager, + asset, + entityName, + morphData, + numWeights, + ); + } + + late final _set_morph_target_weightsPtr = _lookup< + ffi.NativeFunction< + ffi.Void Function( + ffi.Pointer, + EntityId, + ffi.Pointer, + ffi.Pointer, + ffi.Int)>>('set_morph_target_weights'); + late final _set_morph_target_weights = + _set_morph_target_weightsPtr.asFunction< + void Function(ffi.Pointer, int, ffi.Pointer, + ffi.Pointer, int)>(); + int set_morph_animation( ffi.Pointer assetManager, int asset, @@ -1225,8 +1254,6 @@ class ResourceBuffer extends ffi.Struct { } class ResourceLoaderWrapper extends ffi.Struct { - external ffi.Pointer mOwner; - external LoadResource mLoadResource; external FreeResource mFreeResource; @@ -1234,6 +1261,8 @@ class ResourceLoaderWrapper extends ffi.Struct { external LoadResourceFromOwner mLoadResourceFromOwner; external FreeResourceFromOwner mFreeResourceFromOwner; + + external ffi.Pointer mOwner; } typedef LoadResource = ffi.Pointer<