finalize bone transform animation
This commit is contained in:
@@ -208,12 +208,13 @@ class _MyAppState extends State<MyApp> {
|
||||
await _filamentController.clearLights();
|
||||
break;
|
||||
case 32:
|
||||
await _filamentController.setBoneTransform(
|
||||
_cube!,
|
||||
"Bone.001",
|
||||
"Cube.001",
|
||||
BoneTransform([Vec3(x: 0, y: 0.0, z: 0.0)],
|
||||
[Quaternion(x: 1, y: 1, z: 1, w: 1)]));
|
||||
|
||||
// await _filamentController.setBoneTransform(
|
||||
// _cube!,
|
||||
// "Bone.001",
|
||||
// "Cube.001",
|
||||
// BoneTransform([Vec3(x: 0, y: 0.0, z: 0.0)],
|
||||
// [Quaternion(x: 1, y: 1, z: 1, w: 1)]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
#include "SceneAssetLoader.hpp"
|
||||
#include "SceneAsset.hpp"
|
||||
#include "SceneResources.hpp"
|
||||
#include "ResourceManagement.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace filament;
|
||||
|
||||
@@ -5,91 +5,105 @@
|
||||
|
||||
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));
|
||||
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 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);
|
||||
///
|
||||
/// A wrapper for a single set of frame-data that may animate multiples bones/mesh nodes.
|
||||
/// [data]
|
||||
///
|
||||
struct BoneAnimation {
|
||||
const char** boneNames;
|
||||
const char** meshNames;
|
||||
float* data;
|
||||
size_t numBones;
|
||||
size_t numMeshTargets;
|
||||
};
|
||||
|
||||
void apply_weights(void* asset, float* const weights, int count);
|
||||
|
||||
void set_animation(
|
||||
void* asset,
|
||||
float* morphData,
|
||||
int numMorphWeights,
|
||||
float* boneData,
|
||||
const char** boneNames,
|
||||
const char** meshNames,
|
||||
int numBones,
|
||||
int numFrames,
|
||||
float frameLengthInMs
|
||||
);
|
||||
typedef struct BoneAnimation BoneAnimation;
|
||||
|
||||
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 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_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);
|
||||
|
||||
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);
|
||||
int get_animation_count(void* asset);
|
||||
|
||||
void get_animation_name(void* asset, char* const outPtr, int index);
|
||||
|
||||
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
|
||||
|
||||
27
ios/include/ResourceManagement.hpp
Normal file
27
ios/include/ResourceManagement.hpp
Normal 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)>;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -17,14 +17,16 @@
|
||||
|
||||
#include <utils/NameComponentManager.h>
|
||||
|
||||
#include "SceneResources.hpp"
|
||||
#include "ResourceManagement.hpp"
|
||||
#include "SceneAssetAnimation.hpp"
|
||||
#include "PolyvoxFilamentApi.h"
|
||||
|
||||
namespace polyvox {
|
||||
using namespace filament;
|
||||
using namespace filament::gltfio;
|
||||
using namespace utils;
|
||||
|
||||
using namespace std;
|
||||
|
||||
class SceneAsset {
|
||||
friend class SceneAssetLoader;
|
||||
public:
|
||||
@@ -71,25 +73,16 @@ namespace polyvox {
|
||||
void setAnimation(
|
||||
float* morphData,
|
||||
int numMorphWeights,
|
||||
float* boneData,
|
||||
const char** boneNames,
|
||||
const char** meshNames,
|
||||
int numBones,
|
||||
BoneAnimation* targets,
|
||||
int numBoneAnimations,
|
||||
int numFrames,
|
||||
float frameLengthInMs
|
||||
);
|
||||
|
||||
void setBoneTransform(
|
||||
const char* boneName,
|
||||
const char* meshName,
|
||||
float transX,
|
||||
float transY,
|
||||
float transZ,
|
||||
float quatX,
|
||||
float quatY,
|
||||
float quatZ,
|
||||
float quatW
|
||||
);
|
||||
void fillEntitiesByName(const char** name, int count, vector<Entity>& out);
|
||||
size_t getBoneIndex(const char* name);
|
||||
|
||||
Entity getNode(const char* name);
|
||||
|
||||
void transformToUnitCube();
|
||||
|
||||
@@ -97,9 +90,7 @@ namespace polyvox {
|
||||
|
||||
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();
|
||||
|
||||
@@ -116,9 +107,17 @@ namespace polyvox {
|
||||
Engine* _engine = nullptr;
|
||||
NameComponentManager* _ncm;
|
||||
|
||||
void updateRuntimeAnimation();
|
||||
void updateEmbeddedAnimations();
|
||||
void setBoneTransform(
|
||||
uint8_t skinIndex,
|
||||
const vector<uint8_t>& boneIndices,
|
||||
const vector<Entity>& targets,
|
||||
const vector<float> data,
|
||||
int frameNumber
|
||||
);
|
||||
|
||||
void updateRuntimeAnimation();
|
||||
|
||||
void updateEmbeddedAnimations();
|
||||
|
||||
Animator* _animator;
|
||||
|
||||
@@ -143,4 +142,4 @@ namespace polyvox {
|
||||
void updateTransform();
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,12 @@
|
||||
#pragma once
|
||||
#ifndef SCENE_ASSET_ANIMATION_H_
|
||||
#define SCENE_ASSET_ANIMATION_H_
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include "utils/Entity.h"
|
||||
|
||||
#include "ResourceBuffer.hpp"
|
||||
|
||||
namespace polyvox {
|
||||
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)>;
|
||||
|
||||
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.
|
||||
//
|
||||
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) {
|
||||
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 frameNumber = -1;
|
||||
int mNumFrames = -1;
|
||||
float mFrameLengthInMs = 0;
|
||||
time_point_t startTime;
|
||||
@@ -115,13 +81,30 @@ namespace polyvox {
|
||||
float* mMorphFrameData = nullptr;
|
||||
int mNumMorphWeights = 0;
|
||||
|
||||
float* mBoneFrameData = nullptr;
|
||||
int mNumBones = 0;
|
||||
|
||||
vector<string> mBoneNames;
|
||||
vector<string> mMeshNames;
|
||||
unique_ptr<vector<BoneTransformTarget>> mTargets;
|
||||
|
||||
RuntimeAnimation(float* morphData,
|
||||
int numMorphWeights,
|
||||
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
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <gltfio/FilamentAsset.h>
|
||||
#include <gltfio/ResourceLoader.h>
|
||||
|
||||
#include "SceneResources.hpp"
|
||||
#include "ResourceManagement.hpp"
|
||||
#include "SceneAsset.hpp"
|
||||
#include "ResourceBuffer.hpp"
|
||||
|
||||
@@ -39,4 +39,4 @@ namespace polyvox {
|
||||
Scene* _scene;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +126,8 @@ public:
|
||||
*/
|
||||
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.
|
||||
*
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
#include <mutex>
|
||||
|
||||
#include "Log.hpp"
|
||||
#include "SceneResources.hpp"
|
||||
#include "ResourceManagement.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "material/image_material.h"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "ResourceBuffer.hpp"
|
||||
|
||||
#include "FilamentViewer.hpp"
|
||||
#include "filament/LightManager.h"
|
||||
#include "Log.hpp"
|
||||
@@ -6,9 +7,8 @@
|
||||
using namespace polyvox;
|
||||
|
||||
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)) {
|
||||
FilamentViewer* v = new FilamentViewer(context, loadResource, freeResource);
|
||||
@@ -148,50 +148,47 @@ extern "C" {
|
||||
void* asset,
|
||||
float* morphData,
|
||||
int numMorphWeights,
|
||||
float* boneData,
|
||||
const char** boneNames,
|
||||
const char** meshNames,
|
||||
int numBones,
|
||||
BoneAnimation* boneAnimations,
|
||||
int numBoneAnimations,
|
||||
int numFrames,
|
||||
float frameLengthInMs) {
|
||||
((SceneAsset*)asset)->setAnimation(
|
||||
morphData,
|
||||
numMorphWeights,
|
||||
boneData,
|
||||
boneNames,
|
||||
meshNames,
|
||||
numBones,
|
||||
boneAnimations,
|
||||
numBoneAnimations,
|
||||
numFrames,
|
||||
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
|
||||
) {
|
||||
((SceneAsset*)asset)->setBoneTransform(
|
||||
boneName,
|
||||
entityName,
|
||||
transX,
|
||||
transY,
|
||||
transZ,
|
||||
quatX,
|
||||
quatY,
|
||||
quatZ,
|
||||
quatW
|
||||
);
|
||||
// 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
|
||||
// ) {
|
||||
// ((SceneAsset*)asset)->setBoneTransform(
|
||||
// boneName,
|
||||
// entityName,
|
||||
// transX,
|
||||
// transY,
|
||||
// transZ,
|
||||
// quatX,
|
||||
// quatY,
|
||||
// quatZ,
|
||||
// quatW,
|
||||
// false
|
||||
// );
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
|
||||
void play_animation(void* asset, int index, bool loop, bool reverse) {
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
#include "StreamBufferAdapter.hpp"
|
||||
#include "SceneAsset.hpp"
|
||||
#include "Log.hpp"
|
||||
#include "SceneResources.hpp"
|
||||
#include "ResourceManagement.hpp"
|
||||
#include "SceneAssetAnimation.hpp"
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
@@ -58,19 +59,58 @@ void SceneAsset::setMorphTargetWeights(float *weights, int count) {
|
||||
void SceneAsset::setAnimation(
|
||||
float* morphData,
|
||||
int numMorphWeights,
|
||||
float* boneData,
|
||||
const char** boneNames,
|
||||
const char** meshNames,
|
||||
int numBones,
|
||||
BoneAnimation* boneAnimations,
|
||||
int numBoneAnimations,
|
||||
int numFrames,
|
||||
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>(
|
||||
morphData,
|
||||
numMorphWeights,
|
||||
boneData,
|
||||
boneNames,
|
||||
meshNames,
|
||||
numBones,
|
||||
transforms,
|
||||
numFrames,
|
||||
frameLengthInMs
|
||||
);
|
||||
@@ -87,50 +127,115 @@ void SceneAsset::updateRuntimeAnimation() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_runtimeAnimationBuffer->frameIndex == -1) {
|
||||
if (_runtimeAnimationBuffer->frameNumber == -1) {
|
||||
_runtimeAnimationBuffer->startTime = high_resolution_clock::now();
|
||||
}
|
||||
|
||||
duration<double, std::milli> dur =
|
||||
high_resolution_clock::now() - _runtimeAnimationBuffer->startTime;
|
||||
int frameIndex =
|
||||
int frameNumber =
|
||||
static_cast<int>(dur.count() / _runtimeAnimationBuffer->mFrameLengthInMs);
|
||||
|
||||
// if the animation has finished, return early
|
||||
if (frameIndex >= _runtimeAnimationBuffer->mNumFrames) {
|
||||
if (frameNumber >= _runtimeAnimationBuffer->mNumFrames) {
|
||||
_runtimeAnimationBuffer = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (frameIndex > _runtimeAnimationBuffer->frameIndex) {
|
||||
_runtimeAnimationBuffer->frameIndex = frameIndex;
|
||||
if (frameNumber > _runtimeAnimationBuffer->frameNumber) {
|
||||
_runtimeAnimationBuffer->frameNumber = frameNumber;
|
||||
if(_runtimeAnimationBuffer->mMorphFrameData) {
|
||||
auto morphFramePtrOffset = frameIndex * _runtimeAnimationBuffer->mNumMorphWeights;
|
||||
auto morphFramePtrOffset = frameNumber * _runtimeAnimationBuffer->mNumMorphWeights;
|
||||
setMorphTargetWeights(_runtimeAnimationBuffer->mMorphFrameData + morphFramePtrOffset,
|
||||
_runtimeAnimationBuffer->mNumMorphWeights);
|
||||
}
|
||||
|
||||
if(_runtimeAnimationBuffer->mBoneFrameData) {
|
||||
|
||||
for(int i = 0; i < _runtimeAnimationBuffer->mNumBones; i++) {
|
||||
// auto boneFramePtrOffset = (frameIndex * _runtimeAnimationBuffer->mNumBones * 7) + (i*7);
|
||||
const char* boneName = _runtimeAnimationBuffer->mBoneNames[i].c_str();
|
||||
const char* meshName = _runtimeAnimationBuffer->mMeshNames[i].c_str();
|
||||
// float* frame = _runtimeAnimationBuffer->mBoneFrameData + boneFramePtrOffset;
|
||||
|
||||
float transX = 0.0f;//frame[0];
|
||||
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);
|
||||
if(_runtimeAnimationBuffer->mTargets->size() > 0) {
|
||||
for(auto& target : *(_runtimeAnimationBuffer->mTargets)) {
|
||||
|
||||
setBoneTransform(
|
||||
target.skinIndex,
|
||||
*(target.mBoneIndices),
|
||||
*(target.mMeshTargets),
|
||||
*(target.mBoneData),
|
||||
frameNumber
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
if (index > _animator->getAnimationCount() - 1) {
|
||||
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();
|
||||
}
|
||||
|
||||
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() {
|
||||
return _asset->getCameraEntities();
|
||||
}
|
||||
@@ -431,3 +476,20 @@ size_t SceneAsset::getLightEntityCount() const noexcept {
|
||||
|
||||
|
||||
} // 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;
|
||||
// }
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "PolyvoxFilamentApi.h"
|
||||
#include "FilamentViewer.hpp"
|
||||
#include "ResourceBuffer.hpp"
|
||||
#include "SceneResources.hpp"
|
||||
#include "ResourceManagement.hpp"
|
||||
#include <functional>
|
||||
|
||||
using namespace polyvox;
|
||||
|
||||
@@ -1,44 +1,7 @@
|
||||
import 'animations.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
import 'package:vector_math/vector_math.dart';
|
||||
|
||||
class AnimationBuilder {
|
||||
BoneAnimation? boneAnimation;
|
||||
@@ -53,7 +16,7 @@ class AnimationBuilder {
|
||||
|
||||
final List<String> _boneNames = [];
|
||||
final List<String> _meshNames = [];
|
||||
final List<BoneTransform> _boneTransforms = [];
|
||||
final List<BoneTransformFrameData> _boneTransforms = [];
|
||||
|
||||
Animation build() {
|
||||
if (_numMorphWeights == 0 || _duration == 0 || _frameLengthInMs == 0)
|
||||
@@ -79,22 +42,31 @@ class AnimationBuilder {
|
||||
print(
|
||||
"Created morphWeights of size ${morphData.length} (${morphData.lengthInBytes} for ${numFrames} frames");
|
||||
|
||||
final boneTransforms = Float32List(numFrames * _boneTransforms.length * 7);
|
||||
print(
|
||||
"Creating bone transforms of size ${numFrames * _boneTransforms.length * 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)}");
|
||||
List<BoneAnimation>? boneAnimations;
|
||||
|
||||
if (_boneTransforms.isNotEmpty) {
|
||||
throw Exception("TODO");
|
||||
boneAnimations = <BoneAnimation>[];
|
||||
|
||||
final boneTransforms =
|
||||
Float32List(numFrames * _boneTransforms.length * 7);
|
||||
|
||||
// print(
|
||||
// "Creating bone transforms of size ${numFrames * _boneTransforms.length * 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,
|
||||
_meshNames, numFrames, _frameLengthInMs);
|
||||
return Animation(morphData, _numMorphWeights, boneAnimations, numFrames,
|
||||
_frameLengthInMs);
|
||||
}
|
||||
|
||||
AnimationBuilder setFramerate(int framerate) {
|
||||
@@ -126,11 +98,11 @@ class AnimationBuilder {
|
||||
String meshName,
|
||||
double start,
|
||||
double end,
|
||||
Vec3 transStart,
|
||||
Vec3 transEnd,
|
||||
Vector3 transStart,
|
||||
Vector3 transEnd,
|
||||
Quaternion quatStart,
|
||||
Quaternion quatEnd) {
|
||||
var translations = <Vec3>[];
|
||||
var translations = <Vector3>[];
|
||||
var quats = <Quaternion>[];
|
||||
var frameStart = (start * 1000) ~/ _frameLengthInMs;
|
||||
var frameEnd = (end * 1000) ~/ _frameLengthInMs;
|
||||
@@ -143,25 +115,25 @@ class AnimationBuilder {
|
||||
if (i >= frameStart && i < frameEnd) {
|
||||
var linear = (i - frameStart) / (frameEnd - frameStart);
|
||||
|
||||
translations.add(Vec3(
|
||||
x: ((1 - linear) * transStart.x) + (linear * transEnd.x),
|
||||
y: ((1 - linear) * transStart.y) + (linear * transEnd.y),
|
||||
z: ((1 - linear) * transStart.z) + (linear * transEnd.z),
|
||||
translations.add(Vector3(
|
||||
((1 - linear) * transStart.x) + (linear * transEnd.x),
|
||||
((1 - linear) * transStart.y) + (linear * transEnd.y),
|
||||
((1 - linear) * transStart.z) + (linear * transEnd.z),
|
||||
));
|
||||
|
||||
quats.add(Quaternion(
|
||||
x: ((1 - linear) * quatStart.x) + (linear * quatEnd.x),
|
||||
y: ((1 - linear) * quatStart.y) + (linear * quatEnd.y),
|
||||
z: ((1 - linear) * quatStart.z) + (linear * quatEnd.z),
|
||||
w: ((1 - linear) * quatStart.w) + (linear * quatEnd.w),
|
||||
((1 - linear) * quatStart.x) + (linear * quatEnd.x),
|
||||
((1 - linear) * quatStart.y) + (linear * quatEnd.y),
|
||||
((1 - linear) * quatStart.z) + (linear * quatEnd.z),
|
||||
((1 - linear) * quatStart.w) + (linear * quatEnd.w),
|
||||
));
|
||||
} else {
|
||||
translations.add(Vec3());
|
||||
quats.add(Quaternion());
|
||||
translations.add(Vector3.zero());
|
||||
quats.add(Quaternion.identity());
|
||||
}
|
||||
}
|
||||
|
||||
_boneTransforms.add(BoneTransform(translations, quats));
|
||||
_boneTransforms.add(BoneTransformFrameData(translations, quats));
|
||||
|
||||
_boneNames.add(boneName);
|
||||
_meshNames.add(meshName);
|
||||
|
||||
@@ -1,47 +1,87 @@
|
||||
class Vec3 {
|
||||
final double x;
|
||||
final double y;
|
||||
final double z;
|
||||
import 'dart:typed_data';
|
||||
|
||||
Vec3({this.x = 0, this.y = 0, this.z = 0});
|
||||
import 'package:vector_math/vector_math.dart';
|
||||
|
||||
factory Vec3.from(List<double> vals) =>
|
||||
Vec3(x: vals[0], y: vals[1], z: vals[2]);
|
||||
// class Vec3 {
|
||||
// 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 {
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
double z = 0;
|
||||
double w = 1;
|
||||
class Animation {
|
||||
late final Float32List? morphData;
|
||||
final int numMorphWeights;
|
||||
|
||||
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) =>
|
||||
Quaternion(x: vals[0], y: vals[1], z: vals[2], w: vals[3]);
|
||||
final List<BoneAnimation>? boneAnimations;
|
||||
|
||||
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 {
|
||||
final List<Vec3> translations;
|
||||
class BoneTransformFrameData {
|
||||
final List<Vector3> translations;
|
||||
final List<Quaternion> quaternions;
|
||||
|
||||
///
|
||||
/// The length of [translations] and [quaternions] must be the same;
|
||||
/// 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) {
|
||||
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* {
|
||||
@@ -54,22 +94,3 @@ class BoneTransform {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,8 +80,8 @@ abstract class FilamentController {
|
||||
Future setPosition(FilamentAsset asset, double x, double y, double z);
|
||||
Future setRotation(
|
||||
FilamentAsset asset, double rads, double x, double y, double z);
|
||||
Future setBoneTransform(FilamentAsset asset, String boneName, String meshName,
|
||||
BoneTransform transform);
|
||||
// Future setBoneTransform(FilamentAsset asset, String boneName, String meshName,
|
||||
// BoneTransform transform);
|
||||
Future setScale(FilamentAsset asset, double scale);
|
||||
Future setCameraFocalLength(double focalLength);
|
||||
Future setCameraFocusDistance(double focusDistance);
|
||||
@@ -282,14 +282,11 @@ class PolyvoxFilamentController extends FilamentController {
|
||||
}
|
||||
|
||||
Future setAnimation(FilamentAsset asset, Animation animation) async {
|
||||
print("Frmael en ${animation.frameLengthInMs}");
|
||||
await _channel.invokeMethod("setAnimation", [
|
||||
asset,
|
||||
animation.morphData!,
|
||||
animation.numMorphWeights,
|
||||
animation.boneTransforms ?? Float32List(0),
|
||||
animation.boneNames ?? <String>[],
|
||||
animation.meshNames ?? <String>[],
|
||||
animation.boneAnimations?.map((a) => a.toList()).toList() ?? [],
|
||||
animation.numFrames,
|
||||
animation.frameLengthInMs
|
||||
]);
|
||||
@@ -367,21 +364,21 @@ class PolyvoxFilamentController extends FilamentController {
|
||||
await _channel.invokeMethod("setPosition", [asset, x, y, z]);
|
||||
}
|
||||
|
||||
Future setBoneTransform(FilamentAsset asset, String boneName, String meshName,
|
||||
BoneTransform transform) async {
|
||||
await _channel.invokeMethod("setBoneTransform", [
|
||||
asset,
|
||||
boneName,
|
||||
meshName,
|
||||
transform.translations[0].x,
|
||||
transform.translations[0].y,
|
||||
transform.translations[0].z,
|
||||
transform.quaternions[0].x,
|
||||
transform.quaternions[0].y,
|
||||
transform.quaternions[0].z,
|
||||
transform.quaternions[0].w
|
||||
]);
|
||||
}
|
||||
// Future setBoneTransform(FilamentAsset asset, String boneName, String meshName,
|
||||
// BoneTransform transform) async {
|
||||
// await _channel.invokeMethod("setBoneTransform", [
|
||||
// asset,
|
||||
// boneName,
|
||||
// meshName,
|
||||
// transform.translations[0].x,
|
||||
// transform.translations[0].y,
|
||||
// transform.translations[0].z,
|
||||
// transform.quaternions[0].x,
|
||||
// transform.quaternions[0].y,
|
||||
// transform.quaternions[0].z,
|
||||
// transform.quaternions[0].w
|
||||
// ]);
|
||||
// }
|
||||
|
||||
Future setScale(FilamentAsset asset, double scale) async {
|
||||
await _channel.invokeMethod("setScale", [asset, scale]);
|
||||
|
||||
@@ -265,27 +265,27 @@ static FlMethodResponse* _set_position(PolyvoxFilamentPlugin* self, FlMethodCall
|
||||
return FL_METHOD_RESPONSE(fl_method_success_response_new(result));
|
||||
}
|
||||
|
||||
static FlMethodResponse* _set_bone_transform(PolyvoxFilamentPlugin* self, FlMethodCall* 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 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));
|
||||
// static FlMethodResponse* _set_bone_transform(PolyvoxFilamentPlugin* self, FlMethodCall* 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 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));
|
||||
|
||||
set_bone_transform(
|
||||
assetPtr,
|
||||
boneName,
|
||||
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, 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, 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, 8)), // quatZ
|
||||
(float)fl_value_get_float(fl_value_get_list_value(args, 9)) // quatW
|
||||
);
|
||||
g_autoptr(FlValue) result = fl_value_new_string("OK");
|
||||
return FL_METHOD_RESPONSE(fl_method_success_response_new(result));
|
||||
}
|
||||
// set_bone_transform(
|
||||
// assetPtr,
|
||||
// boneName,
|
||||
// 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, 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, 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, 8)), // quatZ
|
||||
// (float)fl_value_get_float(fl_value_get_list_value(args, 9)) // quatW
|
||||
// );
|
||||
// g_autoptr(FlValue) result = fl_value_new_string("OK");
|
||||
// return FL_METHOD_RESPONSE(fl_method_success_response_new(result));
|
||||
// }
|
||||
|
||||
static FlMethodResponse* _set_camera_position(PolyvoxFilamentPlugin* self, FlMethodCall* 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));
|
||||
|
||||
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);
|
||||
int64_t numBones = fl_value_get_length(boneNamesValue);
|
||||
size_t numBoneAnimations = fl_value_get_length(flBoneAnimations);
|
||||
|
||||
const char** boneNames = nullptr;
|
||||
const char** meshNames = nullptr;
|
||||
if(numBones > 0) {
|
||||
boneNames = new const char*[numBones];
|
||||
meshNames = new const char*[numBones];
|
||||
vector<BoneAnimation> boneAnimations;
|
||||
boneAnimations.resize(numBoneAnimations);
|
||||
|
||||
for(int i = 0; i < numBoneAnimations; i++) {
|
||||
|
||||
|
||||
for(int i=0; i< numBones;i++) {
|
||||
boneNames[i] = fl_value_get_string(fl_value_get_list_value(boneNamesValue, i));
|
||||
FlValue* flBoneAnimation = fl_value_get_list_value(flBoneAnimations, 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);
|
||||
|
||||
for(int i=0; i< numBones;i++) {
|
||||
meshNames[i] = fl_value_get_string(fl_value_get_list_value(meshNamesValue, i));
|
||||
|
||||
vector<const char*> meshNames;
|
||||
meshNames.resize(fl_value_get_length(flMeshNames));
|
||||
for(int i=0; i < meshNames.size(); 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, 7));
|
||||
set_animation(assetPtr, morphData, numMorphWeights, boneData, boneNames, meshNames, numBones, numFrames, frameLengthInMs);
|
||||
float frameLengthInMs = fl_value_get_float(fl_value_get_list_value(args, 5));
|
||||
|
||||
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");
|
||||
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) {
|
||||
response = _set_position(self, method_call);
|
||||
} else if(strcmp(method, "setBoneTransform") == 0) {
|
||||
response = _set_bone_transform(self, method_call);
|
||||
// response = _set_bone_transform(self, method_call);
|
||||
} else {
|
||||
response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new());
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ environment:
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
vector_math: ^2.1.2
|
||||
plugin_platform_interface: ^2.0.0
|
||||
|
||||
dev_dependencies:
|
||||
|
||||
Reference in New Issue
Block a user