allow adding AnimationComponent/morph target animations to arbitrary entities

This commit is contained in:
Nick Fisher
2024-04-26 10:51:38 +08:00
parent 6fe436a5cc
commit f2efb0d7d1
2 changed files with 616 additions and 471 deletions

View File

@@ -30,10 +30,9 @@ namespace flutter_filament
using namespace filament; using namespace filament;
using namespace filament::gltfio; using namespace filament::gltfio;
using namespace utils; using namespace utils;
using std::vector;
using std::unique_ptr;
using std::string; using std::string;
using std::unique_ptr;
using std::vector;
class SceneManager class SceneManager
{ {
@@ -43,25 +42,24 @@ namespace flutter_filament
Scene *scene, Scene *scene,
const char *uberArchivePath); const char *uberArchivePath);
~SceneManager(); ~SceneManager();
EntityId loadGltf(const char *uri, const char *relativeResourcePath); EntityId loadGltf(const char *uri, const char *relativeResourcePath);
//// ////
/// @brief Load the GLB from the specified path, optionally creating multiple instances. /// @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 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. /// @param numInstances the number of instances to create.
/// @return an Entity representing the FilamentAsset associated with the loaded FilamentAsset. /// @return an Entity representing the FilamentAsset associated with the loaded FilamentAsset.
/// ///
EntityId loadGlb(const char *uri, int numInstances); EntityId loadGlb(const char *uri, int numInstances);
EntityId loadGlbFromBuffer(const uint8_t* data, size_t length, int numInstances=1); EntityId loadGlbFromBuffer(const uint8_t *data, size_t length, int numInstances = 1);
EntityId createInstance(EntityId entityId); EntityId createInstance(EntityId entityId);
void remove(EntityId entity); void remove(EntityId entity);
void destroyAll(); void destroyAll();
unique_ptr<vector<string>> getAnimationNames(EntityId entity); unique_ptr<vector<string>> getAnimationNames(EntityId entity);
float getAnimationDuration(EntityId entity, int animationIndex); float getAnimationDuration(EntityId entity, int animationIndex);
unique_ptr<vector<string>> getMorphTargetNames(EntityId entity, const char *name); unique_ptr<vector<string>> getMorphTargetNames(EntityId entity, const char *name);
void transformToUnitCube(EntityId e); void transformToUnitCube(EntityId e);
inline void updateTransform(EntityId e); inline void updateTransform(EntityId e);
@@ -81,23 +79,22 @@ namespace flutter_filament
bool setMorphAnimationBuffer( bool setMorphAnimationBuffer(
EntityId entityId, EntityId entityId,
const char *entityName,
const float *const morphData, const float *const morphData,
const int *const morphIndices, const int *const morphIndices,
int numMorphTargets, int numMorphTargets,
int numFrames, int numFrames,
float frameLengthInMs); float frameLengthInMs);
void setMorphTargetWeights(EntityId entityId, const char *const entityName, const float *const weights, int count); bool setMorphTargetWeights(EntityId entityId, const float *const weights, int count);
/// @brief Set the local transform for the bone at boneIndex/skinIndex in the given entity. /// @brief Set the local transform for the bone at boneIndex/skinIndex in the given entity.
/// @param entityId the parent entity /// @param entityId the parent entity
/// @param entityName the name of the mesh under entityId for which the bone will be set. /// @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 skinIndex the index of the joint skin. Currently only 0 is supported.
/// @param boneName the name of the bone /// @param boneName the name of the bone
/// @param transform the 4x4 matrix representing the local transform for the bone /// @param transform the 4x4 matrix representing the local transform for the bone
/// @return true if the transform was successfully set, false otherwise /// @return true if the transform was successfully set, false otherwise
bool setBoneTransform(EntityId entityId, const char *entityName, int skinIndex, const char* boneName, math::mat4f transform); bool setBoneTransform(EntityId entityId, const char *entityName, int skinIndex, const char *boneName, math::mat4f transform);
/// @brief Set frame data to animate the given bones/entities. /// @brief Set frame data to animate the given bones/entities.
/// @param entity the parent entity /// @param entity the parent entity
@@ -105,7 +102,7 @@ namespace flutter_filament
/// @param numFrames the number of frames /// @param numFrames the number of frames
/// @param boneName the name of the bone to animate /// @param boneName the name of the bone to animate
/// @param meshName an array of mesh names under [entity] that should be animated /// @param meshName an array of mesh names under [entity] that should be animated
/// @param numMeshTargets the number of meshes under [meshName] /// @param numMeshTargets the number of meshes under [meshName]
/// @param frameLengthInMs the length of each frame in ms /// @param frameLengthInMs the length of each frame in ms
/// @return true if the bone animation was successfully enqueued /// @return true if the bone animation was successfully enqueued
bool addBoneAnimation( bool addBoneAnimation(
@@ -115,7 +112,7 @@ namespace flutter_filament
const char *const boneName, const char *const boneName,
const char **const meshName, const char **const meshName,
int numMeshTargets, int numMeshTargets,
float frameLengthInMs, float frameLengthInMs,
bool isModelSpace); bool isModelSpace);
void resetBones(EntityId entityId); void resetBones(EntityId entityId);
void playAnimation(EntityId e, int index, bool loop, bool reverse, bool replaceActive, float crossfade = 0.3f); void playAnimation(EntityId e, int index, bool loop, bool reverse, bool replaceActive, float crossfade = 0.3f);
@@ -131,36 +128,33 @@ namespace flutter_filament
const char *entityName); const char *entityName);
int getEntityCount(EntityId entity, bool renderableOnly); int getEntityCount(EntityId entity, bool renderableOnly);
void getEntities(EntityId entity, bool renderableOnly, EntityId *out); void getEntities(EntityId entity, bool renderableOnly, EntityId *out);
const char* getEntityNameAt(EntityId entity, int index, bool renderableOnly); const char *getEntityNameAt(EntityId entity, int index, bool renderableOnly);
void addCollisionComponent(EntityId entity, void (*onCollisionCallback)(const EntityId entityId1, const EntityId entityId2), bool affectsCollidingTransform); void addCollisionComponent(EntityId entity, void (*onCollisionCallback)(const EntityId entityId1, const EntityId entityId2), bool affectsCollidingTransform);
void removeCollisionComponent(EntityId entityId); void removeCollisionComponent(EntityId entityId);
void setParent(EntityId child, EntityId parent); void setParent(EntityId child, EntityId parent);
void addAnimationComponent(EntityId entity); bool addAnimationComponent(EntityId entity);
/// @brief returns the number of instances of the FilamentAsset represented by the given entity. /// @brief returns the number of instances of the FilamentAsset represented by the given entity.
/// @param entityId /// @param entityId
/// @return the number of instances /// @return the number of instances
int getInstanceCount(EntityId entityId); int getInstanceCount(EntityId entityId);
/// @brief returns an array containing all instances of the FilamentAsset represented by the given entity. /// @brief returns an array containing all instances of the FilamentAsset represented by the given entity.
/// @param entityId /// @param entityId
void getInstances(EntityId entityId, EntityId* out); void getInstances(EntityId entityId, EntityId *out);
/// ///
/// Sets the draw priority for the given entity. See RenderableManager.h for more details. /// Sets the draw priority for the given entity. See RenderableManager.h for more details.
/// ///
void setPriority(EntityId entity, int priority); void setPriority(EntityId entity, int priority);
/// @brief returns the gizmo entity, used to manipulate the global transform for entities /// @brief returns the gizmo entity, used to manipulate the global transform for entities
/// @param out a pointer to an array of three EntityId {x, y, z} /// @param out a pointer to an array of three EntityId {x, y, z}
/// @return /// @return
/// ///
void getGizmo(EntityId* out); void getGizmo(EntityId *out);
friend class FilamentViewer; friend class FilamentViewer;
private: private:
gltfio::AssetLoader *_assetLoader = nullptr; gltfio::AssetLoader *_assetLoader = nullptr;
@@ -172,30 +166,30 @@ namespace flutter_filament
gltfio::TextureProvider *_stbDecoder = nullptr; gltfio::TextureProvider *_stbDecoder = nullptr;
gltfio::TextureProvider *_ktxDecoder = nullptr; gltfio::TextureProvider *_ktxDecoder = nullptr;
std::mutex _mutex; std::mutex _mutex;
Material* _gizmoMaterial; Material *_gizmoMaterial;
utils::NameComponentManager* _ncm; utils::NameComponentManager *_ncm;
tsl::robin_map< tsl::robin_map<
EntityId, EntityId,
gltfio::FilamentInstance*> _instances; gltfio::FilamentInstance *>
tsl::robin_map<EntityId, gltfio::FilamentAsset*> _assets; _instances;
tsl::robin_map<EntityId, std::tuple<math::float3,bool,math::quatf,bool,float>> _transformUpdates; tsl::robin_map<EntityId, gltfio::FilamentAsset *> _assets;
tsl::robin_map<EntityId, std::tuple<math::float3, bool, math::quatf, bool, float>> _transformUpdates;
AnimationComponentManager* _animationComponentManager = nullptr; AnimationComponentManager *_animationComponentManager = nullptr;
CollisionComponentManager* _collisionComponentManager = nullptr; CollisionComponentManager *_collisionComponentManager = nullptr;
gltfio::FilamentInstance* getInstanceByEntityId(EntityId entityId); gltfio::FilamentInstance *getInstanceByEntityId(EntityId entityId);
gltfio::FilamentAsset* getAssetByEntityId(EntityId entityId); gltfio::FilamentAsset *getAssetByEntityId(EntityId entityId);
utils::Entity findEntityByName( utils::Entity findEntityByName(
const gltfio::FilamentInstance* instance, const gltfio::FilamentInstance *instance,
const char *entityName); const char *entityName);
EntityId addGizmo(); EntityId addGizmo();
utils::Entity _gizmoX; utils::Entity _gizmoX;
utils::Entity _gizmoY; utils::Entity _gizmoY;
utils::Entity _gizmoZ; utils::Entity _gizmoZ;
}; };
} }

File diff suppressed because it is too large Load Diff