From b28097b0544ed37570206b33211a0d77b59be99f Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Mon, 7 Feb 2022 13:19:20 +0800 Subject: [PATCH] add fixes for setting camera --- android/src/main/cpp/filament_api.cpp | 10 +- example/assets/cube.bin | Bin 82588 -> 88796 bytes example/assets/cube.gltf | 282 +++++++++++++------------- example/lib/main.dart | 8 +- ios/src/FilamentViewer.cpp | 104 ++++++---- ios/src/FilamentViewer.hpp | 2 +- lib/filament_controller.dart | 5 + 7 files changed, 228 insertions(+), 183 deletions(-) diff --git a/android/src/main/cpp/filament_api.cpp b/android/src/main/cpp/filament_api.cpp index 54a91b0f..89f1b322 100644 --- a/android/src/main/cpp/filament_api.cpp +++ b/android/src/main/cpp/filament_api.cpp @@ -49,8 +49,8 @@ extern "C" { ((FilamentViewer*)viewer)->loadGltf(assetPath, relativePath); } - void set_camera(void* viewer, const char* nodeName) { - ((FilamentViewer*)viewer)->setCamera(nodeName); + bool set_camera(void* viewer, const char* nodeName) { + return ((FilamentViewer*)viewer)->setCamera(nodeName); } void* filament_viewer_new( @@ -133,10 +133,12 @@ extern "C" { } } - void free_pointer(void** ptr, int size) { + void free_pointer(char*** ptr, int size) { + __android_log_print(ANDROID_LOG_VERBOSE, "filament_api", "Freeing %d char pointers", size); for(int i = 0; i < size; i++) { - free(ptr[i]); + free((*ptr)[i]); } + free(*ptr); } void release_source_assets(void* viewer) { diff --git a/example/assets/cube.bin b/example/assets/cube.bin index 830b692b940ca08e1e3b4eff82cbff802ef2f5f5..ff00a72ca6e5622ba8c98a21ccde4c28d101303a 100644 GIT binary patch delta 4274 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 delta 3541 zcma)<4Ommx8OQ&JZ_JGZfpXN;)lsqH)KLqxXsxr<>N>3JOgiUE zt*m4R4RzKrwN_VMsnLc?5?JlFuB$8Cx{Xz|u4OB3Y^76y7LdO83UcIm@@(Aaeb2q` z`#=A4a`N%~=r|p`e`m0xG2Kxb?N}-~stk^1E016XzJwVZ1yfxoS&@cM)Q0hCS`&Xz zYv5_x7~ZUn=O1e`xkVe!=S+;}l{5}$<6ZkEmTCBeIGLwVET-5NXXGd27)2;1AOumAqY#T2OoBvNLIiXOL^$Pe+=gHTAdGStG>C*2pbP{-#y7A6 zQ}H0yBLS;Xg?M}mI}isO9!Db9p%&9nhW$vvcknZq@EqPmrVT&D+n9nM;V=w1fJWSj za1B=wz?R`EK1C4wI~F03g|O?m zAHnQz7{W#5VGxWBU^#~ISA2oJWMBhIQHeE}jEyKpIc~?-QG$o?0Ftm4 zypgqYU9wCeabt41Yfo~7M%vPoW=7FxXR3PAyreM6=XUJ1yt`ws&szSbcU)7picR|9 zjQ-j6v(B3nt{wDEr5G*JXcrAc4Xq?w#e!(;Z<1&%>Rr~1HVrSEZ{W4_kI}0N)X1MK z(^@`SruF6RdMUSY=@m1&)_YFSsH`iAO|>viVY1oFB65>cTD++#EoM`lUsM?vKMn!dS1M8+1#L;>0Omqiuc_`6!2C@;6B|77f&s6q{;coWkG=d!$;!Pi;2v&dr~zpFp{O;UUYV+d90; z*ga>JFY=j-YAExI#X>`++pL7WFVN#}l6VB7Ui48nCK^z|B#Y{CO<59~t}eS?;`KE; zURxvaqcsLsdrgH#dgI_;v;D2tb7)k)NV2rueIRFgUx2UG7vfP0CQ%_a#XX~`I{W^G zl3Dv$pE7B(O?VdP`PaZC37G9sBAv{O}P2zjWjr zyk%(L@+i*kfi(c>H7l>XR?AJjwY;;}%JciIypclJZ{?dP-tM=$QTC#)bF$;EH4?=@K3)?3{vzwdO#mKGLh#Dj1<=k z#TQ14o&miiF5%q7n0&)TH>kgHlR0`*F*s)X{9xkEC0-j$yv1ZsH1lSH~2f*>ss@K&PRNaE5c;^3!= za$|{FX!JAJJ$9mJzqEBk)>55WSMX zYy&}cDZzOlT_J?u;VOe7Z9Kp z(6t!0LgLyYLgD4ab*t%mfb2_Ex(_GLS4`toyXmS?mTIv;om{BSTCM8CRb`T@$x*w@ z)q0FtDWLljqRBP%zrf?dmz{21&FrZlw@%BhGN&$rS)CP1YEqJ { _filamentController.zoom(-1.0); }, child: const Text('zoom in')), + ElevatedButton( onPressed: () { _filamentController.zoom(1.0); }, child: const Text('zoom out')), + ElevatedButton( + onPressed: () { + _filamentController.setCamera("Camera.001"); + }, + child: const Text('Set Camera')), Builder(builder:(innerCtx) => ElevatedButton( onPressed: () async { final names = await _filamentController - .getTargetNames("Cube"); + .getTargetNames("Cube.001"); await showDialog( builder: (ctx) { diff --git a/ios/src/FilamentViewer.cpp b/ios/src/FilamentViewer.cpp index 7dae42ce..32f665dc 100644 --- a/ios/src/FilamentViewer.cpp +++ b/ios/src/FilamentViewer.cpp @@ -268,10 +268,10 @@ void FilamentViewer::loadGlb(const char* const uri) { Log("Loading GLB at URI %s", uri); if(_asset) { + _asset->releaseSourceData(); _resourceLoader->evictResourceData(); _scene->removeEntities(_asset->getEntities(), _asset->getEntityCount()); _assetLoader->destroyAsset(_asset); - _freeResource(_assetBuffer); } _asset = nullptr; _animator = nullptr; @@ -339,55 +339,83 @@ void FilamentViewer::loadGltf(const char* const uri, const char* const relativeR Log("Load complete for GLTF at URI %s", uri); - transformToUnitCube(); + // transformToUnitCube(); } -void FilamentViewer::setCamera(const char* cameraName) { +bool FilamentViewer::setCamera(const char* cameraName) { FFilamentAsset* asset = (FFilamentAsset*)_asset; gltfio::NodeMap &sourceNodes = asset->isInstanced() ? asset->mInstances[0]->nodeMap : asset->mNodeMap; - + Log("Setting camera to %s", cameraName); for (auto pair : sourceNodes) { cgltf_node const *node = pair.first; - if(node->camera) { - Log("Got camera %s of type %s ", node->camera->name, node->camera->type); + if(!node->camera) { + if(node->name) { + Log("No camera found under node %s", node->name); + } else { + Log("No camera found under unnamed node."); + } + continue; + } - if(strcmp(cameraName, node->camera->name) == 0) { - filament::math::mat4 mat( - node->matrix[0], - node->matrix[1], - node->matrix[2], - node->matrix[3], - node->matrix[4], - node->matrix[5], - node->matrix[6], - node->matrix[7], - node->matrix[8], - node->matrix[9], - node->matrix[10], - node->matrix[11], - node->parent->translation[0], - node->parent->translation[1], - node->parent->translation[2], - 1 - ); + Log("Found camera under node %s", node->name); - quatf rot1(node->parent->rotation[0],node->parent->rotation[1], node->parent->rotation[2], node->parent->rotation[3]); - quatf rot2(node->rotation[0],node->rotation[1], node->rotation[2], node->rotation[3]); - quatf rot3 = rot1 * rot2; - filament::math::mat4 rotm(rot3); - + if(node->camera->name) { + Log("Checking camera : %s", node->camera->name); + } + + if(strcmp(cameraName, node->camera->name) == 0) { + Log("Found camera."); + filament::math::mat4 mat( + node->matrix[0], + node->matrix[1], + node->matrix[2], + node->matrix[3], + node->matrix[4], + node->matrix[5], + node->matrix[6], + node->matrix[7], + node->matrix[8], + node->matrix[9], + node->matrix[10], + node->matrix[11], + node->parent->translation[0], + node->parent->translation[1], + node->parent->translation[2], + 1 + ); + + quatf rot1(node->parent->rotation[0],node->parent->rotation[1], node->parent->rotation[2], node->parent->rotation[3]); + quatf rot2(node->rotation[0],node->rotation[1], node->rotation[2], node->rotation[3]); + quatf rot3 = rot1 * rot2; + filament::math::mat4 rotm(rot3); + filament::math::mat4 result = mat * rotm; + Entity cameraEntity = EntityManager::get().create(); + Camera* cam = _engine->createCamera(cameraEntity); + + const Viewport& vp = _view->getViewport(); + + const double aspect = (double)vp.width / vp.height; + + cam->setLensProjection(_cameraFocalLength, aspect, kNearPlane, kFarPlane); + + if(!cam) { + Log("Couldn't create camera"); + } else { _engine->getTransformManager().setTransform( - _engine->getTransformManager().getInstance(_mainCamera->getEntity()), result); - - } + _engine->getTransformManager().getInstance(cameraEntity), result); + + _view->setCamera(cam); + return true; + } } } + return false; } StringList FilamentViewer::getTargetNames(const char* meshName) { @@ -404,18 +432,12 @@ StringList FilamentViewer::getTargetNames(const char* meshName) { cgltf_node const *node = pair.first; cgltf_mesh const *mesh = node->mesh; - if(node->camera) { - Log("Got camera %s of type %s", node->camera->name, node->camera->type); - } - if (mesh) { Log("Mesh : %s ",mesh->name); if(strcmp(meshName, mesh->name) == 0) { return StringList((const char**)mesh->target_names, (int) mesh->target_names_count); } - } else { - Log("No mesh attached to node"); - } + } } return StringList(nullptr, 0); } @@ -429,7 +451,7 @@ void FilamentViewer::loadSkybox(const char* const skyboxPath, const char* const new image::KtxBundle(static_cast(skyboxBuffer.data), static_cast(skyboxBuffer.size)); _skyboxTexture = image::ktx::createTexture(_engine, skyboxBundle, false); _skybox = filament::Skybox::Builder().environment(_skyboxTexture).build(*_engine); - // _skybox = Skybox::Builder().color({0.1, 0.125, 0.25, 1.0}).build(*_engine); + _scene->setSkybox(_skybox); _freeResource(skyboxBuffer); diff --git a/ios/src/FilamentViewer.hpp b/ios/src/FilamentViewer.hpp index f25bb990..d4f00f82 100644 --- a/ios/src/FilamentViewer.hpp +++ b/ios/src/FilamentViewer.hpp @@ -90,7 +90,7 @@ namespace polyvox { // void animateWeights(float* data, int numWeights, int length, float frameRate); // void animateBones(); void playAnimation(int index); - void setCamera(const char* nodeName); + bool setCamera(const char* nodeName); void destroySwapChain(); void createSwapChain(void* surface); diff --git a/lib/filament_controller.dart b/lib/filament_controller.dart index f5da820e..27423482 100644 --- a/lib/filament_controller.dart +++ b/lib/filament_controller.dart @@ -17,6 +17,7 @@ abstract class FilamentController { Future> getTargetNames(String meshName); Future releaseSourceAssets(); Future playAnimation(int index); + Future setCamera(String name); /// /// Set the weights of all morph targets in the mesh to the specified weights at successive frames (where [framerate] is the number of times per second the weights should be updated). @@ -121,4 +122,8 @@ class PolyvoxFilamentController extends FilamentController { Future playAnimation(int index) async { await _channel.invokeMethod("playAnimation", index); } + + Future setCamera(String name) async { + await _channel.invokeMethod("setCamera", name); + } }