finalize bone transform animation

This commit is contained in:
Nick Fisher
2022-12-17 16:31:20 +08:00
parent de9797a20e
commit b1832c237f
17 changed files with 581 additions and 476 deletions

View File

@@ -208,12 +208,13 @@ class _MyAppState extends State<MyApp> {
await _filamentController.clearLights(); await _filamentController.clearLights();
break; break;
case 32: case 32:
await _filamentController.setBoneTransform(
_cube!, // await _filamentController.setBoneTransform(
"Bone.001", // _cube!,
"Cube.001", // "Bone.001",
BoneTransform([Vec3(x: 0, y: 0.0, z: 0.0)], // "Cube.001",
[Quaternion(x: 1, y: 1, z: 1, w: 1)])); // BoneTransform([Vec3(x: 0, y: 0.0, z: 0.0)],
// [Quaternion(x: 1, y: 1, z: 1, w: 1)]));
break; break;
} }
} }

View File

@@ -33,7 +33,7 @@
#include "SceneAssetLoader.hpp" #include "SceneAssetLoader.hpp"
#include "SceneAsset.hpp" #include "SceneAsset.hpp"
#include "SceneResources.hpp" #include "ResourceManagement.hpp"
using namespace std; using namespace std;
using namespace filament; using namespace filament;

View File

@@ -5,91 +5,105 @@
typedef struct ResourceBuffer ResourceBuffer; typedef struct ResourceBuffer ResourceBuffer;
//ResourceBuffer create_resource_buffer(const void* data, const uint32_t size, const uint32_t id); ///
void* filament_viewer_new(void* context, ResourceBuffer (*loadResource)(const char*), void (*freeResource)(uint32_t)); /// A wrapper for a single set of frame-data that may animate multiples bones/mesh nodes.
void* filament_viewer_delete(void* viewer); /// [data]
void create_render_target(void* viewer, uint32_t textureId, uint32_t width, uint32_t height); ///
void set_background_image(void* viewer, const char* path); struct BoneAnimation {
void set_background_image_position(void* viewer, float x, float y, bool clamp); const char** boneNames;
void load_skybox(void* viewer, const char* skyboxPath); const char** meshNames;
void load_ibl(void* viewer, const char* iblPath); float* data;
void remove_skybox(void* viewer); size_t numBones;
void remove_ibl(void* viewer); size_t numMeshTargets;
int32_t add_light(void* viewer, uint8_t type, float colour, float intensity, float posX, float posY, float posZ, float dirX, float dirY, float dirZ, bool shadows); };
void remove_light(void* viewer, int32_t entityId);
void clear_lights(void* viewer);
void* load_glb(void* viewer, const char* assetPath);
void* load_gltf(void* viewer, const char* assetPath, const char* relativePath);
bool set_camera(void* viewer, void* asset, const char* nodeName);
void render(void* viewer, uint64_t frameTimeInNanos);
void create_swap_chain(void* viewer, void* surface, uint32_t width, uint32_t height);
void destroy_swap_chain(void* viewer);
void set_frame_interval(void* viewer, float interval);
void* get_renderer(void* viewer);
void update_viewport_and_camera_projection(void* viewer, int width, int height, float scaleFactor);
void scroll_begin(void* viewer);
void scroll_update(void* viewer, float x, float y , float z);
void scroll_end(void* viewer);
void grab_begin(void* viewer, float x, float y, bool pan);
void grab_update(void* viewer, float x, float y);
void grab_end(void* viewer);
void apply_weights(void* asset, float* const weights, int count); typedef struct BoneAnimation BoneAnimation;
void set_animation(
void* asset,
float* morphData,
int numMorphWeights,
float* boneData,
const char** boneNames,
const char** meshNames,
int numBones,
int numFrames,
float frameLengthInMs
);
void set_bone_transform(
void* asset,
const char* boneName,
const char* entityName,
float transX,
float transY,
float transZ,
float quatX,
float quatY,
float quatZ,
float quatW
);
void play_animation(void* asset, int index, bool loop, bool reverse);
void stop_animation(void* asset, int index);
int get_animation_count(void* asset); extern "C" {
void* filament_viewer_new(void* context, ResourceBuffer (*loadResource)(const char*), void (*freeResource)(uint32_t));
void filament_viewer_delete(void* viewer);
void create_render_target(void* viewer, uint32_t textureId, uint32_t width, uint32_t height);
void set_background_image(void* viewer, const char* path);
void set_background_image_position(void* viewer, float x, float y, bool clamp);
void load_skybox(void* viewer, const char* skyboxPath);
void load_ibl(void* viewer, const char* iblPath);
void remove_skybox(void* viewer);
void remove_ibl(void* viewer);
int32_t add_light(void* viewer, uint8_t type, float colour, float intensity, float posX, float posY, float posZ, float dirX, float dirY, float dirZ, bool shadows);
void remove_light(void* viewer, int32_t entityId);
void clear_lights(void* viewer);
void* load_glb(void* viewer, const char* assetPath);
void* load_gltf(void* viewer, const char* assetPath, const char* relativePath);
bool set_camera(void* viewer, void* asset, const char* nodeName);
void render(void* viewer, uint64_t frameTimeInNanos);
void create_swap_chain(void* viewer, void* surface, uint32_t width, uint32_t height);
void destroy_swap_chain(void* viewer);
void set_frame_interval(void* viewer, float interval);
void* get_renderer(void* viewer);
void update_viewport_and_camera_projection(void* viewer, int width, int height, float scaleFactor);
void get_animation_name(void* asset, char* const outPtr, int index); void scroll_begin(void* viewer);
void scroll_update(void* viewer, float x, float y , float z);
void scroll_end(void* viewer);
void grab_begin(void* viewer, float x, float y, bool pan);
void grab_update(void* viewer, float x, float y);
void grab_end(void* viewer);
void get_morph_target_name(void* asset, const char* meshName, char* const outPtr, int index ); void apply_weights(void* asset, float* const weights, int count);
void set_animation(
void* asset,
float* morphData,
int numMorphWeights,
BoneAnimation* boneAnimations,
int numBoneAnimations,
int numFrames,
float frameLengthInMs
);
int get_morph_target_name_count(void* asset, const char* meshName); // void set_bone_transform(
// void* asset,
void remove_asset(void* viewer, void* asset); // const char* boneName,
// const char* entityName,
void clear_assets(void* viewer); // float transX,
// float transY,
void load_texture(void* asset, const char* assetPath, int renderableIndex); // float transZ,
void set_texture(void* asset); // float quatX,
// float quatY,
void transform_to_unit_cube(void* asset); // float quatZ,
// float quatW
void set_position(void* asset, float x, float y, float z); // );
void set_rotation(void* asset, float rads, float x, float y, float z);
void set_scale(void* asset, float scale); void play_animation(void* asset, int index, bool loop, bool reverse);
void stop_animation(void* asset, int index);
void set_camera_position(void* viewer, float x, float y, float z); int get_animation_count(void* asset);
void set_camera_rotation(void* viewer, float rads, float x, float y, float z);
void set_camera_focal_length(void* viewer, float focalLength); void get_animation_name(void* asset, char* const outPtr, int index);
void set_camera_focus_distance(void* viewer, float focusDistance);
void get_morph_target_name(void* asset, const char* meshName, char* const outPtr, int index );
int get_morph_target_name_count(void* asset, const char* meshName);
void remove_asset(void* viewer, void* asset);
void clear_assets(void* viewer);
void load_texture(void* asset, const char* assetPath, int renderableIndex);
void set_texture(void* asset);
void transform_to_unit_cube(void* asset);
void set_position(void* asset, float x, float y, float z);
void set_rotation(void* asset, float rads, float x, float y, float z);
void set_scale(void* asset, float scale);
void set_camera_position(void* viewer, float x, float y, float z);
void set_camera_rotation(void* viewer, float rads, float x, float y, float z);
void set_camera_focal_length(void* viewer, float focalLength);
void set_camera_focus_distance(void* viewer, float focusDistance);
}
#endif #endif

View File

@@ -0,0 +1,27 @@
#pragma once
#include <functional>
#include <memory>
#include <chrono>
#include <iostream>
#include <vector>
#include "ResourceBuffer.hpp"
namespace polyvox {
using namespace std;
//
// Typedef for a function that loads a resource into a ResourceBuffer from an asset URI.
//
using LoadResource = function<ResourceBuffer(const char* uri)>;
//
// Typedef for a function that frees an ID associated with a ResourceBuffer.
//
using FreeResource = function<void (uint32_t)>;
}

View File

@@ -17,14 +17,16 @@
#include <utils/NameComponentManager.h> #include <utils/NameComponentManager.h>
#include "SceneResources.hpp" #include "ResourceManagement.hpp"
#include "SceneAssetAnimation.hpp"
#include "PolyvoxFilamentApi.h"
namespace polyvox { namespace polyvox {
using namespace filament; using namespace filament;
using namespace filament::gltfio; using namespace filament::gltfio;
using namespace utils; using namespace utils;
using namespace std; using namespace std;
class SceneAsset { class SceneAsset {
friend class SceneAssetLoader; friend class SceneAssetLoader;
public: public:
@@ -71,25 +73,16 @@ namespace polyvox {
void setAnimation( void setAnimation(
float* morphData, float* morphData,
int numMorphWeights, int numMorphWeights,
float* boneData, BoneAnimation* targets,
const char** boneNames, int numBoneAnimations,
const char** meshNames,
int numBones,
int numFrames, int numFrames,
float frameLengthInMs float frameLengthInMs
); );
void setBoneTransform( void fillEntitiesByName(const char** name, int count, vector<Entity>& out);
const char* boneName, size_t getBoneIndex(const char* name);
const char* meshName,
float transX, Entity getNode(const char* name);
float transY,
float transZ,
float quatX,
float quatY,
float quatZ,
float quatW
);
void transformToUnitCube(); void transformToUnitCube();
@@ -97,9 +90,7 @@ namespace polyvox {
void setPosition(float x, float y, float z); void setPosition(float x, float y, float z);
void setRotation(float rads, float x, float y, float z); void setRotation(float rads, float x, float y, float z);
const utils::Entity* getCameraEntities(); const utils::Entity* getCameraEntities();
@@ -116,9 +107,17 @@ namespace polyvox {
Engine* _engine = nullptr; Engine* _engine = nullptr;
NameComponentManager* _ncm; NameComponentManager* _ncm;
void updateRuntimeAnimation(); void setBoneTransform(
void updateEmbeddedAnimations(); uint8_t skinIndex,
const vector<uint8_t>& boneIndices,
const vector<Entity>& targets,
const vector<float> data,
int frameNumber
);
void updateRuntimeAnimation();
void updateEmbeddedAnimations();
Animator* _animator; Animator* _animator;
@@ -143,4 +142,4 @@ namespace polyvox {
void updateTransform(); void updateTransform();
}; };
} }

View File

@@ -1,27 +1,12 @@
#pragma once #ifndef SCENE_ASSET_ANIMATION_H_
#define SCENE_ASSET_ANIMATION_H_
#include <functional> #include "utils/Entity.h"
#include <memory>
#include <chrono>
#include <iostream>
#include <vector>
#include "ResourceBuffer.hpp" namespace polyvox {
namespace polyvox {
using namespace std; using namespace std;
//
// Typedef for a function that loads a resource into a ResourceBuffer from an asset URI.
//
using LoadResource = function<ResourceBuffer(const char* uri)>;
//
// Typedef for a function that frees an ID associated with a ResourceBuffer.
//
using FreeResource = function<void (uint32_t)>;
typedef std::chrono::time_point<std::chrono::high_resolution_clock> time_point_t; typedef std::chrono::time_point<std::chrono::high_resolution_clock> time_point_t;
// //
@@ -66,48 +51,29 @@ namespace polyvox {
}; };
///
/// Holds a single set of frame data that may be used to animate multiple bones/meshes.
///
struct BoneTransformTarget {
size_t skinIndex = 0;
unique_ptr<vector<uint8_t>> mBoneIndices;
unique_ptr<vector<utils::Entity>> mMeshTargets;
unique_ptr<vector<float>> mBoneData;
BoneTransformTarget(
unique_ptr<vector<uint8_t>>& boneIndices,
unique_ptr<vector<utils::Entity>>& meshTargets,
unique_ptr<vector<float>>& boneData) : mBoneIndices(move(boneIndices)), mMeshTargets(move(meshTargets)), mBoneData(move(boneData)) {}
};
// //
// An animation created by manually passing frame data for morph weights/bone transforms. // An animation created by manually passing frame data for morph weights/bone transforms.
// //
struct RuntimeAnimation { struct RuntimeAnimation {
RuntimeAnimation(float* morphData,
int numMorphWeights,
float* boneData,
const char** boneNames,
const char** meshNames,
int numBones,
int numFrames,
float frameLengthInMs) :
mNumFrames(numFrames),
mFrameLengthInMs(frameLengthInMs),
mNumMorphWeights(numMorphWeights),
mNumBones(numBones) {
if(numMorphWeights > 0) { int frameNumber = -1;
size_t morphSize = numMorphWeights * mNumFrames * sizeof(float);
mMorphFrameData = (float*)malloc(morphSize);
memcpy(mMorphFrameData, morphData, morphSize);
}
if(numBones > 0) {
size_t boneSize = numBones * numFrames * 7 * sizeof(float);
mBoneFrameData = (float*)malloc(boneSize);
memcpy(mBoneFrameData, boneData, boneSize);
}
for(int i =0; i < numBones; i++) {
mBoneNames.push_back(string(boneNames[i]));
mMeshNames.push_back(string(meshNames[i]));
}
}
~RuntimeAnimation() {
delete(mMorphFrameData);
delete(mBoneFrameData);
}
int frameIndex = -1;
int mNumFrames = -1; int mNumFrames = -1;
float mFrameLengthInMs = 0; float mFrameLengthInMs = 0;
time_point_t startTime; time_point_t startTime;
@@ -115,13 +81,30 @@ namespace polyvox {
float* mMorphFrameData = nullptr; float* mMorphFrameData = nullptr;
int mNumMorphWeights = 0; int mNumMorphWeights = 0;
float* mBoneFrameData = nullptr; unique_ptr<vector<BoneTransformTarget>> mTargets;
int mNumBones = 0;
RuntimeAnimation(float* morphData,
vector<string> mBoneNames; int numMorphWeights,
vector<string> mMeshNames; unique_ptr<vector<BoneTransformTarget>>& targets,
int numFrames,
float frameLengthInMs) :
mNumFrames(numFrames),
mFrameLengthInMs(frameLengthInMs),
mNumMorphWeights(numMorphWeights),
mTargets(move(targets)) {
if(numMorphWeights > 0) {
size_t morphSize = numMorphWeights * mNumFrames * sizeof(float);
mMorphFrameData = (float*)malloc(morphSize);
memcpy(mMorphFrameData, morphData, morphSize);
}
}
~RuntimeAnimation() {
delete(mMorphFrameData);
}
}; };
} }
#endif

View File

@@ -6,7 +6,7 @@
#include <gltfio/FilamentAsset.h> #include <gltfio/FilamentAsset.h>
#include <gltfio/ResourceLoader.h> #include <gltfio/ResourceLoader.h>
#include "SceneResources.hpp" #include "ResourceManagement.hpp"
#include "SceneAsset.hpp" #include "SceneAsset.hpp"
#include "ResourceBuffer.hpp" #include "ResourceBuffer.hpp"
@@ -39,4 +39,4 @@ namespace polyvox {
Scene* _scene; Scene* _scene;
}; };
} }

View File

@@ -126,6 +126,8 @@ public:
*/ */
void detachSkin(size_t skinIndex, utils::Entity target) noexcept; void detachSkin(size_t skinIndex, utils::Entity target) noexcept;
const math::mat4f* getInverseBindMatricesAt(size_t skinIndex) const noexcept;
/** /**
* Resets the AABB on all renderables by manually computing the bounding box. * Resets the AABB on all renderables by manually computing the bounding box.
* *

View File

@@ -70,7 +70,7 @@
#include <mutex> #include <mutex>
#include "Log.hpp" #include "Log.hpp"
#include "SceneResources.hpp" #include "ResourceManagement.hpp"
extern "C" { extern "C" {
#include "material/image_material.h" #include "material/image_material.h"

View File

@@ -1,4 +1,5 @@
#include "ResourceBuffer.hpp" #include "ResourceBuffer.hpp"
#include "FilamentViewer.hpp" #include "FilamentViewer.hpp"
#include "filament/LightManager.h" #include "filament/LightManager.h"
#include "Log.hpp" #include "Log.hpp"
@@ -6,9 +7,8 @@
using namespace polyvox; using namespace polyvox;
extern "C" { extern "C" {
// ResourceBuffer create_resource_buffer(const void* data, const uint32_t size, const uint32_t id) {
// return ResourceBuffer {data, size, id }; #include "PolyvoxFilamentApi.h"
// }
void* filament_viewer_new(void* context, ResourceBuffer (*loadResource)(char const*), void (*freeResource)(unsigned int)) { void* filament_viewer_new(void* context, ResourceBuffer (*loadResource)(char const*), void (*freeResource)(unsigned int)) {
FilamentViewer* v = new FilamentViewer(context, loadResource, freeResource); FilamentViewer* v = new FilamentViewer(context, loadResource, freeResource);
@@ -148,50 +148,47 @@ extern "C" {
void* asset, void* asset,
float* morphData, float* morphData,
int numMorphWeights, int numMorphWeights,
float* boneData, BoneAnimation* boneAnimations,
const char** boneNames, int numBoneAnimations,
const char** meshNames,
int numBones,
int numFrames, int numFrames,
float frameLengthInMs) { float frameLengthInMs) {
((SceneAsset*)asset)->setAnimation( ((SceneAsset*)asset)->setAnimation(
morphData, morphData,
numMorphWeights, numMorphWeights,
boneData, boneAnimations,
boneNames, numBoneAnimations,
meshNames,
numBones,
numFrames, numFrames,
frameLengthInMs frameLengthInMs
); );
} }
void set_bone_transform( // void set_bone_transform(
void* asset, // void* asset,
const char* boneName, // const char* boneName,
const char* entityName, // const char* entityName,
float transX, // float transX,
float transY, // float transY,
float transZ, // float transZ,
float quatX, // float quatX,
float quatY, // float quatY,
float quatZ, // float quatZ,
float quatW // float quatW
) { // ) {
((SceneAsset*)asset)->setBoneTransform( // ((SceneAsset*)asset)->setBoneTransform(
boneName, // boneName,
entityName, // entityName,
transX, // transX,
transY, // transY,
transZ, // transZ,
quatX, // quatX,
quatY, // quatY,
quatZ, // quatZ,
quatW // quatW,
); // false
// );
} // }
void play_animation(void* asset, int index, bool loop, bool reverse) { void play_animation(void* asset, int index, bool loop, bool reverse) {

View File

@@ -16,7 +16,8 @@
#include "StreamBufferAdapter.hpp" #include "StreamBufferAdapter.hpp"
#include "SceneAsset.hpp" #include "SceneAsset.hpp"
#include "Log.hpp" #include "Log.hpp"
#include "SceneResources.hpp" #include "ResourceManagement.hpp"
#include "SceneAssetAnimation.hpp"
using namespace std::chrono; using namespace std::chrono;
@@ -58,19 +59,58 @@ void SceneAsset::setMorphTargetWeights(float *weights, int count) {
void SceneAsset::setAnimation( void SceneAsset::setAnimation(
float* morphData, float* morphData,
int numMorphWeights, int numMorphWeights,
float* boneData, BoneAnimation* boneAnimations,
const char** boneNames, int numBoneAnimations,
const char** meshNames,
int numBones,
int numFrames, int numFrames,
float frameLengthInMs) { float frameLengthInMs) {
auto filamentInstance = _asset->getInstance();
size_t skinCount = filamentInstance->getSkinCount();
if(skinCount > 1) {
Log("WARNING - skin count > 1 not currently implemented. This will probably not work");
}
auto transforms = make_unique<vector<BoneTransformTarget>>();
auto numFloats = numFrames * 7;
for(int i = 0; i < numBoneAnimations; i++) {
auto boneIndices = make_unique<vector<uint8_t>>();
boneIndices->resize(boneAnimations[i].numBones);
for(int j = 0; j < boneAnimations[i].numBones; j++) {
boneIndices->at(j) = getBoneIndex(boneAnimations[i].boneNames[j]);
}
auto meshTargets = make_unique<vector<Entity>>();
for(int j = 0; j < _asset->getEntityCount(); j++) {
for(int k = 0; k < boneAnimations[i].numMeshTargets;k++) {
auto meshName = boneAnimations[i].meshNames[k];
auto entity = _asset->getEntities()[j];
auto nameInstance = _ncm->getInstance(entity);
if(strcmp(meshName,_ncm->getName(nameInstance))==0) {
meshTargets->push_back(entity);
}
}
}
auto frameData = make_unique<vector<float>>(
boneAnimations[i].data,
boneAnimations[i].data + (numFloats * sizeof(float))
);
transforms->push_back(BoneTransformTarget(
boneIndices,
meshTargets,
frameData
));
}
_runtimeAnimationBuffer = std::make_unique<RuntimeAnimation>( _runtimeAnimationBuffer = std::make_unique<RuntimeAnimation>(
morphData, morphData,
numMorphWeights, numMorphWeights,
boneData, transforms,
boneNames,
meshNames,
numBones,
numFrames, numFrames,
frameLengthInMs frameLengthInMs
); );
@@ -87,50 +127,115 @@ void SceneAsset::updateRuntimeAnimation() {
return; return;
} }
if (_runtimeAnimationBuffer->frameIndex == -1) { if (_runtimeAnimationBuffer->frameNumber == -1) {
_runtimeAnimationBuffer->startTime = high_resolution_clock::now(); _runtimeAnimationBuffer->startTime = high_resolution_clock::now();
} }
duration<double, std::milli> dur = duration<double, std::milli> dur =
high_resolution_clock::now() - _runtimeAnimationBuffer->startTime; high_resolution_clock::now() - _runtimeAnimationBuffer->startTime;
int frameIndex = int frameNumber =
static_cast<int>(dur.count() / _runtimeAnimationBuffer->mFrameLengthInMs); static_cast<int>(dur.count() / _runtimeAnimationBuffer->mFrameLengthInMs);
// if the animation has finished, return early // if the animation has finished, return early
if (frameIndex >= _runtimeAnimationBuffer->mNumFrames) { if (frameNumber >= _runtimeAnimationBuffer->mNumFrames) {
_runtimeAnimationBuffer = nullptr; _runtimeAnimationBuffer = nullptr;
return; return;
} }
if (frameIndex > _runtimeAnimationBuffer->frameIndex) { if (frameNumber > _runtimeAnimationBuffer->frameNumber) {
_runtimeAnimationBuffer->frameIndex = frameIndex; _runtimeAnimationBuffer->frameNumber = frameNumber;
if(_runtimeAnimationBuffer->mMorphFrameData) { if(_runtimeAnimationBuffer->mMorphFrameData) {
auto morphFramePtrOffset = frameIndex * _runtimeAnimationBuffer->mNumMorphWeights; auto morphFramePtrOffset = frameNumber * _runtimeAnimationBuffer->mNumMorphWeights;
setMorphTargetWeights(_runtimeAnimationBuffer->mMorphFrameData + morphFramePtrOffset, setMorphTargetWeights(_runtimeAnimationBuffer->mMorphFrameData + morphFramePtrOffset,
_runtimeAnimationBuffer->mNumMorphWeights); _runtimeAnimationBuffer->mNumMorphWeights);
} }
if(_runtimeAnimationBuffer->mBoneFrameData) { if(_runtimeAnimationBuffer->mTargets->size() > 0) {
for(auto& target : *(_runtimeAnimationBuffer->mTargets)) {
for(int i = 0; i < _runtimeAnimationBuffer->mNumBones; i++) {
// auto boneFramePtrOffset = (frameIndex * _runtimeAnimationBuffer->mNumBones * 7) + (i*7); setBoneTransform(
const char* boneName = _runtimeAnimationBuffer->mBoneNames[i].c_str(); target.skinIndex,
const char* meshName = _runtimeAnimationBuffer->mMeshNames[i].c_str(); *(target.mBoneIndices),
// float* frame = _runtimeAnimationBuffer->mBoneFrameData + boneFramePtrOffset; *(target.mMeshTargets),
*(target.mBoneData),
float transX = 0.0f;//frame[0]; frameNumber
float transY = 0.0f;//frame[1]; );
float transZ = 0.0f;//frame[2];
float quatX = 0.0f; //frame[3];
float quatY = 0.0f;//frame[4];
float quatZ = 0.0f; //frame[5];
float quatW = 1.0;//frame[6];
setBoneTransform(boneName, meshName, transX, transY, transZ, quatX, quatY, quatZ, quatW);
} }
} }
} }
} }
size_t SceneAsset::getBoneIndex(const char* name) {
auto filamentInstance = _asset->getInstance();
int skinIndex = 0;
const utils::Entity* joints = filamentInstance->getJointsAt(skinIndex);
size_t numJoints = filamentInstance->getJointCountAt(skinIndex);
int boneIndex = -1;
for(int i =0; i < numJoints; i++) {
const char* jointName = _ncm->getName(_ncm->getInstance(joints[i]));
if(strcmp(jointName, name) == 0) {
boneIndex = i;
break;
}
}
if(boneIndex == -1) {
Log("Failed to find bone index %d for bone %s", name);
}
return boneIndex;
}
void SceneAsset::setBoneTransform(
uint8_t skinIndex,
const vector<uint8_t>& boneIndices,
const vector<Entity>& targets,
const vector<float> data,
int frameNumber) {
auto filamentInstance = _asset->getInstance();
RenderableManager &rm = _engine->getRenderableManager();
TransformManager &transformManager = _engine->getTransformManager();
auto frameDataOffset = frameNumber * 7;
for(auto& target : targets) {
auto renderable = rm.getInstance(target);
math::mat4f inverseGlobalTransform = inverse(
transformManager.getWorldTransform(
transformManager.getInstance(target)
)
);
for(auto boneIndex : boneIndices) {
utils::Entity joint = filamentInstance->getJointsAt(skinIndex)[boneIndex];
math::mat4f localTransform(math::quatf{
data[frameDataOffset+6],
data[frameDataOffset+3],
data[frameDataOffset+4],
data[frameDataOffset+5]
});
const math::mat4f& inverseBindMatrix = filamentInstance->getInverseBindMatricesAt(skinIndex)[boneIndex];
auto jointInstance = transformManager.getInstance(joint);
math::mat4f globalJointTransform = transformManager.getWorldTransform(jointInstance);
math::mat4f boneTransform = inverseGlobalTransform * globalJointTransform * localTransform * inverseBindMatrix;
rm.setBones(
renderable,
&boneTransform,
1, boneIndex);
}
}
}
void SceneAsset::playAnimation(int index, bool loop, bool reverse) { void SceneAsset::playAnimation(int index, bool loop, bool reverse) {
if (index > _animator->getAnimationCount() - 1) { if (index > _animator->getAnimationCount() - 1) {
Log("Asset does not contain an animation at index %d", index); Log("Asset does not contain an animation at index %d", index);
@@ -353,66 +458,6 @@ void SceneAsset::setRotation(float rads, float x, float y, float z) {
updateTransform(); updateTransform();
} }
void SceneAsset::setBoneTransform(
const char* boneName,
const char* entityName,
float transX,
float transY,
float transZ,
float quatX,
float quatY,
float quatZ,
float quatW) {
auto filamentInstance = _asset->getInstance();
if(filamentInstance->getSkinCount()) {
// Log("WARNING - skin count > 1 not currently implemented. This will probably not work");
}
// filamentInstance->getAnimator()->resetBoneMatrices();
int skinIndex = 0;
const utils::Entity* joints = filamentInstance->getJointsAt(skinIndex);
size_t numJoints = filamentInstance->getJointCountAt(skinIndex);
int boneIndex = -1;
for(int i =0; i < numJoints; i++) {
const char* jointName = _ncm->getName(_ncm->getInstance(joints[i]));
if(strcmp(jointName, boneName) == 0) {
boneIndex = i;
// Log("Found bone index %d for bone %s", boneIndex, boneName);
break;
}
}
if(boneIndex == -1) {
Log("Failed to find bone index %d for bone %s", boneName);
return;
}
RenderableManager &rm = _engine->getRenderableManager();
// RenderableManager::Bone transform = {
// .unitQuaternion={quatX,quatY,quatZ,quatW},
// .translation={transX,transY,transZ}
// };
for(int j = 0; j < _asset->getEntityCount(); j++) {
Entity e = _asset->getEntities()[j];
if(strcmp(entityName,_ncm->getName(_ncm->getInstance(e)))==0) {
// Log("Setting bone transform on entity %s", _ncm->getName(_ncm->getInstance(e)));
auto inst = rm.getInstance(e);
if(!inst) {
Log("No renderable instance");
}
// rm.setBones(inst, &transform, 1, boneIndex);
}
}
}
const utils::Entity *SceneAsset::getCameraEntities() { const utils::Entity *SceneAsset::getCameraEntities() {
return _asset->getCameraEntities(); return _asset->getCameraEntities();
} }
@@ -431,3 +476,20 @@ size_t SceneAsset::getLightEntityCount() const noexcept {
} // namespace polyvox } // namespace polyvox
// const utils::Entity* joints = filamentInstance->getJointsAt(skinIndex);
// size_t numJoints = filamentInstance->getJointCountAt(skinIndex);
// int boneIndex = -1;
// for(int i =0; i < numJoints; i++) {
// const char* jointName = _ncm->getName(_ncm->getInstance(joints[i]));
// if(strcmp(jointName, boneName) == 0) {
// boneIndex = i;
// joint = joints[i];
// break;
// }
// }
// if(boneIndex == -1) {
// Log("Failed to find bone index %d for bone %s", boneName);
// return;
// }

View File

@@ -1,7 +1,7 @@
#include "PolyvoxFilamentApi.h" #include "PolyvoxFilamentApi.h"
#include "FilamentViewer.hpp" #include "FilamentViewer.hpp"
#include "ResourceBuffer.hpp" #include "ResourceBuffer.hpp"
#include "SceneResources.hpp" #include "ResourceManagement.hpp"
#include <functional> #include <functional>
using namespace polyvox; using namespace polyvox;

View File

@@ -1,44 +1,7 @@
import 'animations.dart'; import 'animations.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:vector_math/vector_math.dart';
class Animation {
late final Float32List? morphData;
final int numMorphWeights;
final int numFrames;
final double frameLengthInMs;
final List<String>? boneNames;
final List<String>? meshNames;
final Float32List? boneTransforms;
Animation(this.morphData, this.numMorphWeights, this.boneTransforms,
this.boneNames, this.meshNames, this.numFrames, this.frameLengthInMs) {
if (morphData != null && morphData!.length != numFrames * numMorphWeights) {
throw Exception("Mismatched animation data with frame length");
}
}
Animation.from(
{required List<List<double>> morphData,
required this.numMorphWeights,
this.boneTransforms,
this.boneNames,
this.meshNames,
required this.numFrames,
required this.frameLengthInMs}) {
if (morphData.length != numFrames) {
throw Exception("Mismatched animation data with frame length");
}
this.morphData = Float32List(numMorphWeights * numFrames);
for (int i = 0; i < numFrames; i++) {
this.morphData!.setRange((i * numMorphWeights),
(i * numMorphWeights) + numMorphWeights, morphData[i]);
}
}
}
class AnimationBuilder { class AnimationBuilder {
BoneAnimation? boneAnimation; BoneAnimation? boneAnimation;
@@ -53,7 +16,7 @@ class AnimationBuilder {
final List<String> _boneNames = []; final List<String> _boneNames = [];
final List<String> _meshNames = []; final List<String> _meshNames = [];
final List<BoneTransform> _boneTransforms = []; final List<BoneTransformFrameData> _boneTransforms = [];
Animation build() { Animation build() {
if (_numMorphWeights == 0 || _duration == 0 || _frameLengthInMs == 0) if (_numMorphWeights == 0 || _duration == 0 || _frameLengthInMs == 0)
@@ -79,22 +42,31 @@ class AnimationBuilder {
print( print(
"Created morphWeights of size ${morphData.length} (${morphData.lengthInBytes} for ${numFrames} frames"); "Created morphWeights of size ${morphData.length} (${morphData.lengthInBytes} for ${numFrames} frames");
final boneTransforms = Float32List(numFrames * _boneTransforms.length * 7); List<BoneAnimation>? boneAnimations;
print(
"Creating bone transforms of size ${numFrames * _boneTransforms.length * 7}"); if (_boneTransforms.isNotEmpty) {
for (int i = 0; i < numFrames; i++) { throw Exception("TODO");
for (int j = 0; j < _boneTransforms.length; j++) { boneAnimations = <BoneAnimation>[];
var frameData = _boneTransforms[j].getFrameData(i).toList();
var rngStart = ((i * _boneTransforms.length) + j) * 7; final boneTransforms =
var rngEnd = rngStart + 7; Float32List(numFrames * _boneTransforms.length * 7);
boneTransforms.setRange(rngStart, rngEnd, frameData);
} // print(
print( // "Creating bone transforms of size ${numFrames * _boneTransforms.length * 7}");
"frameData for frame $i ${boneTransforms.sublist(i * _boneTransforms.length * 7, (i * _boneTransforms.length * 7) + 7)}"); // for (int i = 0; i < numFrames; i++) {
// for (int j = 0; j < _boneTransforms.length; j++) {
// var frameData = _boneTransforms[j].getFrameData(i).toList();
// var rngStart = ((i * _boneTransforms.length) + j) * 7;
// var rngEnd = rngStart + 7;
// boneTransforms.setRange(rngStart, rngEnd, frameData);
// }
// print(
// "frameData for frame $i ${boneTransforms.sublist(i * _boneTransforms.length * 7, (i * _boneTransforms.length * 7) + 7)}");
// }
} }
return Animation(morphData, _numMorphWeights, boneTransforms, _boneNames, return Animation(morphData, _numMorphWeights, boneAnimations, numFrames,
_meshNames, numFrames, _frameLengthInMs); _frameLengthInMs);
} }
AnimationBuilder setFramerate(int framerate) { AnimationBuilder setFramerate(int framerate) {
@@ -126,11 +98,11 @@ class AnimationBuilder {
String meshName, String meshName,
double start, double start,
double end, double end,
Vec3 transStart, Vector3 transStart,
Vec3 transEnd, Vector3 transEnd,
Quaternion quatStart, Quaternion quatStart,
Quaternion quatEnd) { Quaternion quatEnd) {
var translations = <Vec3>[]; var translations = <Vector3>[];
var quats = <Quaternion>[]; var quats = <Quaternion>[];
var frameStart = (start * 1000) ~/ _frameLengthInMs; var frameStart = (start * 1000) ~/ _frameLengthInMs;
var frameEnd = (end * 1000) ~/ _frameLengthInMs; var frameEnd = (end * 1000) ~/ _frameLengthInMs;
@@ -143,25 +115,25 @@ class AnimationBuilder {
if (i >= frameStart && i < frameEnd) { if (i >= frameStart && i < frameEnd) {
var linear = (i - frameStart) / (frameEnd - frameStart); var linear = (i - frameStart) / (frameEnd - frameStart);
translations.add(Vec3( translations.add(Vector3(
x: ((1 - linear) * transStart.x) + (linear * transEnd.x), ((1 - linear) * transStart.x) + (linear * transEnd.x),
y: ((1 - linear) * transStart.y) + (linear * transEnd.y), ((1 - linear) * transStart.y) + (linear * transEnd.y),
z: ((1 - linear) * transStart.z) + (linear * transEnd.z), ((1 - linear) * transStart.z) + (linear * transEnd.z),
)); ));
quats.add(Quaternion( quats.add(Quaternion(
x: ((1 - linear) * quatStart.x) + (linear * quatEnd.x), ((1 - linear) * quatStart.x) + (linear * quatEnd.x),
y: ((1 - linear) * quatStart.y) + (linear * quatEnd.y), ((1 - linear) * quatStart.y) + (linear * quatEnd.y),
z: ((1 - linear) * quatStart.z) + (linear * quatEnd.z), ((1 - linear) * quatStart.z) + (linear * quatEnd.z),
w: ((1 - linear) * quatStart.w) + (linear * quatEnd.w), ((1 - linear) * quatStart.w) + (linear * quatEnd.w),
)); ));
} else { } else {
translations.add(Vec3()); translations.add(Vector3.zero());
quats.add(Quaternion()); quats.add(Quaternion.identity());
} }
} }
_boneTransforms.add(BoneTransform(translations, quats)); _boneTransforms.add(BoneTransformFrameData(translations, quats));
_boneNames.add(boneName); _boneNames.add(boneName);
_meshNames.add(meshName); _meshNames.add(meshName);

View File

@@ -1,47 +1,87 @@
class Vec3 { import 'dart:typed_data';
final double x;
final double y;
final double z;
Vec3({this.x = 0, this.y = 0, this.z = 0}); import 'package:vector_math/vector_math.dart';
factory Vec3.from(List<double> vals) => // class Vec3 {
Vec3(x: vals[0], y: vals[1], z: vals[2]); // final double x;
// final double y;
// final double z;
// Vec3({this.x = 0, this.y = 0, this.z = 0});
// factory Vec3.from(List<double> vals) =>
// Vec3(x: vals[0], y: vals[1], z: vals[2]);
// }
// class Quaternion {
// double x = 0;
// double y = 0;
// double z = 0;
// double w = 1;
// Quaternion({this.x = 0, this.y = 0, this.z = 0, this.w = 1.0});
// factory Quaternion.from(List<double> vals) =>
// Quaternion(x: vals[0], y: vals[1], z: vals[2], w: vals[3]);
// }
class BoneAnimation {
final List<String> boneNames;
final List<String> meshNames;
final Float32List frameData;
BoneAnimation(this.boneNames, this.meshNames, this.frameData);
List<List> toList() {
return [boneNames, meshNames, frameData];
}
} }
class Quaternion { class Animation {
double x = 0; late final Float32List? morphData;
double y = 0; final int numMorphWeights;
double z = 0;
double w = 1;
Quaternion({this.x = 0, this.y = 0, this.z = 0, this.w = 1.0}); final int numFrames;
final double frameLengthInMs;
factory Quaternion.from(List<double> vals) => final List<BoneAnimation>? boneAnimations;
Quaternion(x: vals[0], y: vals[1], z: vals[2], w: vals[3]);
Animation(this.morphData, this.numMorphWeights, this.boneAnimations,
this.numFrames, this.frameLengthInMs) {
if (morphData != null && morphData!.length != numFrames * numMorphWeights) {
throw Exception("Mismatched animation data with frame length");
}
}
Animation.from(
{required List<List<double>> morphData,
required this.numMorphWeights,
this.boneAnimations,
required this.numFrames,
required this.frameLengthInMs}) {
if (morphData.length != numFrames) {
throw Exception("Mismatched animation data with frame length");
}
this.morphData = Float32List(numMorphWeights * numFrames);
for (int i = 0; i < numFrames; i++) {
this.morphData!.setRange((i * numMorphWeights),
(i * numMorphWeights) + numMorphWeights, morphData[i]);
}
}
} }
class BoneTransform { class BoneTransformFrameData {
final List<Vec3> translations; final List<Vector3> translations;
final List<Quaternion> quaternions; final List<Quaternion> quaternions;
/// ///
/// The length of [translations] and [quaternions] must be the same; /// The length of [translations] and [quaternions] must be the same;
/// each entry represents the Vec3/Quaternion for the given frame. /// each entry represents the Vec3/Quaternion for the given frame.
/// ///
BoneTransform(this.translations, this.quaternions) { BoneTransformFrameData(this.translations, this.quaternions) {
if (translations.length != quaternions.length) { if (translations.length != quaternions.length) {
throw Exception("Length of translation/quaternion frames must match"); throw Exception("Length of translation/quaternion frames must match");
} }
// for (int i = 0; i < quaternions.length; i++) {
// _frameData.add(translations[i].x);
// _frameData.add(translations[i].y);
// _frameData.add(translations[i].z);
// _frameData.add(quaternions[i].x);
// _frameData.add(quaternions[i].y);
// _frameData.add(quaternions[i].z);
// _frameData.add(quaternions[i].w);
// }
} }
Iterable<double> getFrameData(int frame) sync* { Iterable<double> getFrameData(int frame) sync* {
@@ -54,22 +94,3 @@ class BoneTransform {
yield quaternions[frame].w; yield quaternions[frame].w;
} }
} }
class BoneAnimation {
final List<BoneTransform> boneTransforms;
final List<String> boneNames;
final List<String> meshNames;
final int numFrames;
BoneAnimation(
this.boneTransforms, this.boneNames, this.meshNames, this.numFrames);
Iterable<double> toFrameData() sync* {
for (int i = 0; i < numFrames; i++) {
for (int j = 0; j < boneTransforms.length; j++) {
yield* boneTransforms[j].getFrameData(i);
}
}
}
}

View File

@@ -80,8 +80,8 @@ abstract class FilamentController {
Future setPosition(FilamentAsset asset, double x, double y, double z); Future setPosition(FilamentAsset asset, double x, double y, double z);
Future setRotation( Future setRotation(
FilamentAsset asset, double rads, double x, double y, double z); FilamentAsset asset, double rads, double x, double y, double z);
Future setBoneTransform(FilamentAsset asset, String boneName, String meshName, // Future setBoneTransform(FilamentAsset asset, String boneName, String meshName,
BoneTransform transform); // BoneTransform transform);
Future setScale(FilamentAsset asset, double scale); Future setScale(FilamentAsset asset, double scale);
Future setCameraFocalLength(double focalLength); Future setCameraFocalLength(double focalLength);
Future setCameraFocusDistance(double focusDistance); Future setCameraFocusDistance(double focusDistance);
@@ -282,14 +282,11 @@ class PolyvoxFilamentController extends FilamentController {
} }
Future setAnimation(FilamentAsset asset, Animation animation) async { Future setAnimation(FilamentAsset asset, Animation animation) async {
print("Frmael en ${animation.frameLengthInMs}");
await _channel.invokeMethod("setAnimation", [ await _channel.invokeMethod("setAnimation", [
asset, asset,
animation.morphData!, animation.morphData!,
animation.numMorphWeights, animation.numMorphWeights,
animation.boneTransforms ?? Float32List(0), animation.boneAnimations?.map((a) => a.toList()).toList() ?? [],
animation.boneNames ?? <String>[],
animation.meshNames ?? <String>[],
animation.numFrames, animation.numFrames,
animation.frameLengthInMs animation.frameLengthInMs
]); ]);
@@ -367,21 +364,21 @@ class PolyvoxFilamentController extends FilamentController {
await _channel.invokeMethod("setPosition", [asset, x, y, z]); await _channel.invokeMethod("setPosition", [asset, x, y, z]);
} }
Future setBoneTransform(FilamentAsset asset, String boneName, String meshName, // Future setBoneTransform(FilamentAsset asset, String boneName, String meshName,
BoneTransform transform) async { // BoneTransform transform) async {
await _channel.invokeMethod("setBoneTransform", [ // await _channel.invokeMethod("setBoneTransform", [
asset, // asset,
boneName, // boneName,
meshName, // meshName,
transform.translations[0].x, // transform.translations[0].x,
transform.translations[0].y, // transform.translations[0].y,
transform.translations[0].z, // transform.translations[0].z,
transform.quaternions[0].x, // transform.quaternions[0].x,
transform.quaternions[0].y, // transform.quaternions[0].y,
transform.quaternions[0].z, // transform.quaternions[0].z,
transform.quaternions[0].w // transform.quaternions[0].w
]); // ]);
} // }
Future setScale(FilamentAsset asset, double scale) async { Future setScale(FilamentAsset asset, double scale) async {
await _channel.invokeMethod("setScale", [asset, scale]); await _channel.invokeMethod("setScale", [asset, scale]);

View File

@@ -265,27 +265,27 @@ static FlMethodResponse* _set_position(PolyvoxFilamentPlugin* self, FlMethodCall
return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); return FL_METHOD_RESPONSE(fl_method_success_response_new(result));
} }
static FlMethodResponse* _set_bone_transform(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { // static FlMethodResponse* _set_bone_transform(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) {
FlValue* args = fl_method_call_get_args(method_call); // FlValue* args = fl_method_call_get_args(method_call);
auto assetPtr = (void*)fl_value_get_int(fl_value_get_list_value(args, 0)); // auto assetPtr = (void*)fl_value_get_int(fl_value_get_list_value(args, 0));
auto boneName = fl_value_get_string(fl_value_get_list_value(args, 1)); // auto boneName = fl_value_get_string(fl_value_get_list_value(args, 1));
auto meshName = fl_value_get_string(fl_value_get_list_value(args, 2)); // auto meshName = fl_value_get_string(fl_value_get_list_value(args, 2));
set_bone_transform( // set_bone_transform(
assetPtr, // assetPtr,
boneName, // boneName,
meshName, // meshName,
(float)fl_value_get_float(fl_value_get_list_value(args, 3)), // transX // (float)fl_value_get_float(fl_value_get_list_value(args, 3)), // transX
(float)fl_value_get_float(fl_value_get_list_value(args, 4)), // transY // (float)fl_value_get_float(fl_value_get_list_value(args, 4)), // transY
(float)fl_value_get_float(fl_value_get_list_value(args, 5)), // transZ // (float)fl_value_get_float(fl_value_get_list_value(args, 5)), // transZ
(float)fl_value_get_float(fl_value_get_list_value(args, 6)), // quatX // (float)fl_value_get_float(fl_value_get_list_value(args, 6)), // quatX
(float)fl_value_get_float(fl_value_get_list_value(args, 7)), // quatY // (float)fl_value_get_float(fl_value_get_list_value(args, 7)), // quatY
(float)fl_value_get_float(fl_value_get_list_value(args, 8)), // quatZ // (float)fl_value_get_float(fl_value_get_list_value(args, 8)), // quatZ
(float)fl_value_get_float(fl_value_get_list_value(args, 9)) // quatW // (float)fl_value_get_float(fl_value_get_list_value(args, 9)) // quatW
); // );
g_autoptr(FlValue) result = fl_value_new_string("OK"); // g_autoptr(FlValue) result = fl_value_new_string("OK");
return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); // return FL_METHOD_RESPONSE(fl_method_success_response_new(result));
} // }
static FlMethodResponse* _set_camera_position(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { static FlMethodResponse* _set_camera_position(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) {
FlValue* args = fl_method_call_get_args(method_call); FlValue* args = fl_method_call_get_args(method_call);
@@ -379,32 +379,62 @@ static FlMethodResponse* _set_animation(PolyvoxFilamentPlugin* self, FlMethodCal
int64_t numMorphWeights = fl_value_get_int(fl_value_get_list_value(args, 2)); int64_t numMorphWeights = fl_value_get_int(fl_value_get_list_value(args, 2));
float* const boneData = (float* const) fl_value_get_float32_list(fl_value_get_list_value(args, 3)); FlValue* flBoneAnimations = fl_value_get_list_value(args, 3);
FlValue* boneNamesValue = fl_value_get_list_value(args, 4); size_t numBoneAnimations = fl_value_get_length(flBoneAnimations);
int64_t numBones = fl_value_get_length(boneNamesValue);
const char** boneNames = nullptr; vector<BoneAnimation> boneAnimations;
const char** meshNames = nullptr; boneAnimations.resize(numBoneAnimations);
if(numBones > 0) {
boneNames = new const char*[numBones]; for(int i = 0; i < numBoneAnimations; i++) {
meshNames = new const char*[numBones];
FlValue* flBoneAnimation = fl_value_get_list_value(flBoneAnimations, i);
for(int i=0; i< numBones;i++) {
boneNames[i] = fl_value_get_string(fl_value_get_list_value(boneNamesValue, i)); FlValue* flBoneNames = fl_value_get_list_value(flBoneAnimation, 0);
FlValue* flMeshNames = fl_value_get_list_value(flBoneAnimation, 1);
float* const frameData = (float* const) fl_value_get_float32_list(fl_value_get_list_value(flBoneAnimation, 2));
vector<const char*> boneNames;
boneNames.resize(fl_value_get_length(flBoneNames));
for(int i=0; i < boneNames.size(); i++) {
boneNames[i] = fl_value_get_string(fl_value_get_list_value(flBoneNames, i)) ;
std::cout << boneNames[i] << std::endl;
} }
FlValue* meshNamesValue = fl_value_get_list_value(args, 5); vector<const char*> meshNames;
meshNames.resize(fl_value_get_length(flMeshNames));
for(int i=0; i< numBones;i++) { for(int i=0; i < meshNames.size(); i++) {
meshNames[i] = fl_value_get_string(fl_value_get_list_value(meshNamesValue, i)); meshNames[i] = fl_value_get_string(fl_value_get_list_value(flMeshNames, i));
} }
auto animation = BoneAnimation();
animation.boneNames = (const char**)malloc(boneNames.size() * sizeof(char*));
memcpy(animation.boneNames, boneNames.data(), boneNames.size() * sizeof(char*));
animation.numBones = boneNames.size();
animation.meshNames = (const char**)malloc(meshNames.size() * sizeof(char*));
memcpy(animation.meshNames, meshNames.data(), meshNames.size() * sizeof(char*));
animation.numMeshTargets = meshNames.size();
animation.data = frameData;
boneAnimations[i] = animation;
} }
int64_t numFrames = fl_value_get_int(fl_value_get_list_value(args, 4));
int64_t numFrames = fl_value_get_int(fl_value_get_list_value(args, 6)); float frameLengthInMs = fl_value_get_float(fl_value_get_list_value(args, 5));
float frameLengthInMs = fl_value_get_float(fl_value_get_list_value(args, 7));
set_animation(assetPtr, morphData, numMorphWeights, boneData, boneNames, meshNames, numBones, numFrames, frameLengthInMs); auto boneAnimationsPointer = boneAnimations.data();
auto boneAnimationsSize = boneAnimations.size();
set_animation(
assetPtr,
morphData,
numMorphWeights,
boneAnimationsPointer,
boneAnimationsSize,
numFrames,
frameLengthInMs);
g_autoptr(FlValue) result = fl_value_new_string("OK"); g_autoptr(FlValue) result = fl_value_new_string("OK");
return FL_METHOD_RESPONSE(fl_method_success_response_new(result)); return FL_METHOD_RESPONSE(fl_method_success_response_new(result));
@@ -536,7 +566,7 @@ static void polyvox_filament_plugin_handle_method_call(
} else if(strcmp(method, "setPosition") == 0) { } else if(strcmp(method, "setPosition") == 0) {
response = _set_position(self, method_call); response = _set_position(self, method_call);
} else if(strcmp(method, "setBoneTransform") == 0) { } else if(strcmp(method, "setBoneTransform") == 0) {
response = _set_bone_transform(self, method_call); // response = _set_bone_transform(self, method_call);
} else { } else {
response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new()); response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new());
} }

View File

@@ -10,7 +10,7 @@ environment:
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
vector_math: ^2.1.2
plugin_platform_interface: ^2.0.0 plugin_platform_interface: ^2.0.0
dev_dependencies: dev_dependencies: