Merge branch 'master' of github.com:nmfisher/polyvox_filament

This commit is contained in:
Nick Fisher
2023-02-26 12:22:14 +08:00
12 changed files with 172 additions and 106 deletions

View File

@@ -41,7 +41,7 @@ endif()
# of modifying this function. # of modifying this function.
function(APPLY_STANDARD_SETTINGS TARGET) function(APPLY_STANDARD_SETTINGS TARGET)
target_compile_features(${TARGET} PUBLIC cxx_std_14) target_compile_features(${TARGET} PUBLIC cxx_std_14)
target_compile_options(${TARGET} PRIVATE -Wall -Werror) target_compile_options(${TARGET} PRIVATE -Wall -Werror -Wno-unused-function)
target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>") target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>")
target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>") target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>")
endfunction() endfunction()

View File

@@ -8,9 +8,10 @@
typedef struct ResourceBuffer ResourceBuffer; typedef struct ResourceBuffer ResourceBuffer;
/// ///
/// A wrapper for a single set of frame-data that may animate multiples bones/mesh nodes. /// Frame data for animating multiples bones for multiple meshes.
/// [data] /// [data]
/// ///
struct BoneAnimation { struct BoneAnimation {
const char* const* const boneNames; const char* const* const boneNames;
const char* const* const meshNames; const char* const* const meshNames;
@@ -52,10 +53,11 @@ void grab_begin(void* viewer, float x, float y, bool pan);
void grab_update(void* viewer, float x, float y); void grab_update(void* viewer, float x, float y);
void grab_end(void* viewer); void grab_end(void* viewer);
void apply_weights(void* asset, float* const weights, int count); void apply_weights(void* asset, const char* const entityName, float* const weights, int count);
void set_animation( void set_animation(
void* asset, void* asset,
const char* const entityName,
const float* const morphData, const float* const morphData,
int numMorphWeights, int numMorphWeights,
const BoneAnimation* const boneAnimations, const BoneAnimation* const boneAnimations,

View File

@@ -63,10 +63,10 @@ namespace polyvox {
void setAnimationFrame(int animationIndex, int animationFrame); void setAnimationFrame(int animationIndex, int animationFrame);
/// ///
/// Manually set the weights for all morph targets in the assets to the provided values. /// Set the weights for all [count] morph targets in this asset's entity named [inst] to [weights].
/// See [setAnimation] if you want to do the same across a number of frames (and extended to bone transforms). /// See [setAnimation] if you want to do the same across a number of frames (and extended to bone transforms).
/// ///
void setMorphTargetWeights(float* weights, int count); void setMorphTargetWeights(const char* const entityName, float* weights, int count);
/// ///
/// Animates the asset's morph targets/bone transforms according to the frame weights/transforms specified in [morphData]/[boneData]. /// Animates the asset's morph targets/bone transforms according to the frame weights/transforms specified in [morphData]/[boneData].
@@ -76,6 +76,7 @@ namespace polyvox {
/// [morphData] and [boneData] will both be copied, so remember to free these after calling this function. /// [morphData] and [boneData] will both be copied, so remember to free these after calling this function.
/// ///
void setAnimation( void setAnimation(
const char* entityName,
const float* const morphData, const float* const morphData,
int numMorphWeights, int numMorphWeights,
const BoneAnimation* const targets, const BoneAnimation* const targets,
@@ -84,7 +85,6 @@ namespace polyvox {
float frameLengthInMs float frameLengthInMs
); );
void fillEntitiesByName(const char** name, int count, vector<Entity>& out);
size_t getBoneIndex(const char* name); size_t getBoneIndex(const char* name);
Entity getNode(const char* name); Entity getNode(const char* name);

View File

@@ -2,10 +2,13 @@
#define SCENE_ASSET_ANIMATION_H_ #define SCENE_ASSET_ANIMATION_H_
#include "utils/Entity.h" #include "utils/Entity.h"
#include <filament/RenderableManager.h>
namespace polyvox { namespace polyvox {
using namespace std; using namespace std;
using Instance = utils::EntityInstance<filament::RenderableManager>;
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;
@@ -73,21 +76,26 @@ namespace polyvox {
// //
struct RuntimeAnimation { struct RuntimeAnimation {
Instance mInstance;
int frameNumber = -1; int frameNumber = -1;
int mNumFrames = -1; int mNumFrames = -1;
float mFrameLengthInMs = 0; float mFrameLengthInMs = 0;
time_point_t startTime; time_point_t startTime;
float* mMorphFrameData = nullptr; float* mMorphFrameData = nullptr;
int mNumMorphWeights = 0; int mNumMorphWeights = 0;
unique_ptr<vector<BoneTransformTarget>> mTargets; unique_ptr<vector<BoneTransformTarget>> mTargets;
RuntimeAnimation(const float* const morphData, RuntimeAnimation(Instance instance,
const float* const morphData,
int numMorphWeights, int numMorphWeights,
unique_ptr<vector<BoneTransformTarget>>& targets, unique_ptr<vector<BoneTransformTarget>>& targets,
int numFrames, int numFrames,
float frameLengthInMs) : float frameLengthInMs) :
mInstance(instance),
mNumFrames(numFrames), mNumFrames(numFrames),
mFrameLengthInMs(frameLengthInMs), mFrameLengthInMs(frameLengthInMs),
mNumMorphWeights(numMorphWeights), mNumMorphWeights(numMorphWeights),

View File

@@ -141,12 +141,13 @@ extern "C" {
((FilamentViewer*)viewer)->grabEnd(); ((FilamentViewer*)viewer)->grabEnd();
} }
void apply_weights(void* asset, float* const weights, int count) { void apply_weights(void* asset, const char* const entityName, float* const weights, int count) {
((SceneAsset*)asset)->setMorphTargetWeights(weights, count); ((SceneAsset*)asset)->setMorphTargetWeights(entityName, weights, count);
} }
void set_animation( void set_animation(
void* asset, void* asset,
const char* const entityName,
const float* const morphData, const float* const morphData,
int numMorphWeights, int numMorphWeights,
const BoneAnimation* const boneAnimations, const BoneAnimation* const boneAnimations,
@@ -154,6 +155,7 @@ extern "C" {
int numFrames, int numFrames,
float frameLengthInMs) { float frameLengthInMs) {
((SceneAsset*)asset)->setAnimation( ((SceneAsset*)asset)->setAnimation(
entityName,
morphData, morphData,
numMorphWeights, numMorphWeights,
boneAnimations, boneAnimations,

View File

@@ -4,6 +4,7 @@
#include <filament/Engine.h> #include <filament/Engine.h>
#include <filament/TransformManager.h> #include <filament/TransformManager.h>
#include <filament/Texture.h> #include <filament/Texture.h>
#include <filament/RenderableManager.h>
#include <gltfio/Animator.h> #include <gltfio/Animator.h>
#include <gltfio/AssetLoader.h> #include <gltfio/AssetLoader.h>
@@ -48,15 +49,12 @@ SceneAsset::~SceneAsset() {
} }
} }
void SceneAsset::setMorphTargetWeights(float *weights, int count) { void SceneAsset::setMorphTargetWeights(const char* const entityName, float *weights, int count) {
RenderableManager &rm = _engine->getRenderableManager(); // TODO
for (size_t i = 0, c = _asset->getEntityCount(); i != c; ++i) {
auto inst = rm.getInstance(_asset->getEntities()[i]);
rm.setMorphWeights(inst, weights, count);
}
} }
void SceneAsset::setAnimation( void SceneAsset::setAnimation(
const char* entityName,
const float* const morphData, const float* const morphData,
int numMorphWeights, int numMorphWeights,
const BoneAnimation* const boneAnimations, const BoneAnimation* const boneAnimations,
@@ -107,13 +105,31 @@ void SceneAsset::setAnimation(
frameData frameData
)); ));
} }
_runtimeAnimationBuffer = std::make_unique<RuntimeAnimation>(
morphData, RenderableManager &rm = _engine->getRenderableManager();
numMorphWeights, Instance inst;
transforms, for (size_t i = 0, c = _asset->getEntityCount(); i != c; ++i) {
numFrames, auto entity = _asset->getEntities()[i];
frameLengthInMs auto name = _ncm->getName(_ncm->getInstance(entity));
);
if(strcmp(entityName,name)==0) {
inst = rm.getInstance(_asset->getEntities()[i]);
}
}
if(!inst) {
Log("Warning: failed to find Renderable instance for entity %s", entityName);
} else {
_runtimeAnimationBuffer = std::make_unique<RuntimeAnimation>(
inst,
morphData,
numMorphWeights,
transforms,
numFrames,
frameLengthInMs
);
}
} }
void SceneAsset::updateAnimations() { void SceneAsset::updateAnimations() {
@@ -142,12 +158,15 @@ void SceneAsset::updateRuntimeAnimation() {
return; return;
} }
RenderableManager &rm = _engine->getRenderableManager();
if (frameNumber > _runtimeAnimationBuffer->frameNumber) { if (frameNumber > _runtimeAnimationBuffer->frameNumber) {
_runtimeAnimationBuffer->frameNumber = frameNumber; _runtimeAnimationBuffer->frameNumber = frameNumber;
if(_runtimeAnimationBuffer->mMorphFrameData) { if(_runtimeAnimationBuffer->mMorphFrameData) {
auto morphFramePtrOffset = frameNumber * _runtimeAnimationBuffer->mNumMorphWeights; auto morphFramePtrOffset = frameNumber * _runtimeAnimationBuffer->mNumMorphWeights;
setMorphTargetWeights(_runtimeAnimationBuffer->mMorphFrameData + morphFramePtrOffset, rm.setMorphWeights(
_runtimeAnimationBuffer->mNumMorphWeights); _runtimeAnimationBuffer->mInstance,
_runtimeAnimationBuffer->mMorphFrameData + morphFramePtrOffset,
_runtimeAnimationBuffer->mNumMorphWeights);
} }
if(_runtimeAnimationBuffer->mTargets->size() > 0) { if(_runtimeAnimationBuffer->mTargets->size() > 0) {

View File

@@ -97,9 +97,6 @@ SceneAsset *SceneAssetLoader::fromGlb(const char *uri) {
_scene->addEntities(asset->getEntities(), entityCount); _scene->addEntities(asset->getEntities(), entityCount);
Log("Added %d entities to scene", entityCount); Log("Added %d entities to scene", entityCount);
size_t lightEntityCount = asset->getLightEntityCount();
Log("Found %d light entities in scene.", lightEntityCount );
_resourceLoader->loadResources(asset); _resourceLoader->loadResources(asset);
@@ -115,6 +112,10 @@ SceneAsset *SceneAssetLoader::fromGlb(const char *uri) {
rm.setCulling(entityInstance, true); rm.setCulling(entityInstance, true);
} }
auto lights = asset->getLightEntities();
_scene->addEntities(lights, asset->getLightEntityCount());
Log("Added %d lights to scene from asset", asset->getLightEntityCount());
FilamentInstance* inst = asset->getInstance(); FilamentInstance* inst = asset->getInstance();
inst->getAnimator()->updateBoneMatrices(); inst->getAnimator()->updateBoneMatrices();
@@ -131,8 +132,15 @@ SceneAsset *SceneAssetLoader::fromGlb(const char *uri) {
} }
void SceneAssetLoader::remove(SceneAsset *asset) { void SceneAssetLoader::remove(SceneAsset *asset) {
Log("Removing asset and all associated entities/lights.");
_scene->removeEntities(asset->_asset->getEntities(), _scene->removeEntities(asset->_asset->getEntities(),
asset->_asset->getEntityCount()); asset->_asset->getEntityCount());
_scene->removeEntities(asset->getLightEntities(),
asset->getLightEntityCount());
_resourceLoader->evictResourceData(); _resourceLoader->evictResourceData();
_assetLoader->destroyAsset(asset->_asset); _assetLoader->destroyAsset(asset->_asset);
delete asset; delete asset;

View File

@@ -15,7 +15,7 @@ class AnimationBuilder {
List<BoneAnimation>? _boneAnimations = null; List<BoneAnimation>? _boneAnimations = null;
Animation build() { Animation build(String meshName, List<String> morphNames) {
if (_numMorphWeights == 0 || _duration == 0 || _frameLengthInMs == 0) if (_numMorphWeights == 0 || _duration == 0 || _frameLengthInMs == 0)
throw Exception(); throw Exception();
@@ -36,8 +36,11 @@ class AnimationBuilder {
} }
} }
return Animation(morphData, _numMorphWeights, _boneAnimations, numFrames, var morphAnimation =
_frameLengthInMs); MorphAnimation(meshName, morphData, morphNames, _frameLengthInMs);
return Animation(
morphAnimation: morphAnimation, boneAnimations: _boneAnimations);
} }
AnimationBuilder setFramerate(int framerate) { AnimationBuilder setFramerate(int framerate) {

View File

@@ -2,29 +2,6 @@ import 'dart:typed_data';
import 'package:vector_math/vector_math.dart'; import 'package:vector_math/vector_math.dart';
// 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 { class BoneAnimation {
final List<String> boneNames; final List<String> boneNames;
final List<String> meshNames; final List<String> meshNames;
@@ -37,37 +14,33 @@ class BoneAnimation {
} }
} }
class Animation { //
late final Float32List? morphData; // Frame weights for the morph targets specified in [morphNames] attached to mesh [meshName].
final int numMorphWeights; // morphData is laid out as numFrames x numMorphTargets
// where the weights are in the same order as [morphNames].
// [morphNames] must be provided but is not used directly; this is only used to check that the eventual asset being animated contains the same morph targets in the same order.
//
class MorphAnimation {
final String meshName;
final List<String> morphNames;
late final Float32List morphData;
MorphAnimation(
this.meshName, this.morphData, this.morphNames, this.frameLengthInMs);
int get numMorphWeights => morphNames.length;
int get numFrames => morphData.length ~/ numMorphWeights;
final int numFrames;
final double frameLengthInMs; final double frameLengthInMs;
}
class Animation {
final MorphAnimation? morphAnimation;
final List<BoneAnimation>? boneAnimations; final List<BoneAnimation>? boneAnimations;
Animation(this.morphData, this.numMorphWeights, this.boneAnimations, Animation({this.morphAnimation, 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 BoneTransformFrameData { class BoneTransformFrameData {
@@ -94,3 +67,18 @@ class BoneTransformFrameData {
yield quaternions[frame].w; yield quaternions[frame].w;
} }
} }
// Animation.from(
// {required this.meshName,
// 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");
// }
// }
// not directly used, the list of morph targets animated by this [Animation], and may be a subset of the actual morph targets in the asset (and may also be ordered differently).
// // When passed to a [FilamentController], these will be re-mapped appropriately (and any morph targets not provided will be set to zero at each frame).

View File

@@ -300,11 +300,12 @@ class PolyvoxFilamentController extends FilamentController {
Future setAnimation(FilamentAsset asset, Animation animation) async { Future setAnimation(FilamentAsset asset, Animation animation) async {
await _channel.invokeMethod("setAnimation", [ await _channel.invokeMethod("setAnimation", [
asset, asset,
animation.morphData!, animation.morphAnimation!.meshName,
animation.numMorphWeights, animation.morphAnimation!.morphData,
animation.morphAnimation!.numMorphWeights,
animation.boneAnimations?.map((a) => a.toList()).toList() ?? [], animation.boneAnimations?.map((a) => a.toList()).toList() ?? [],
animation.numFrames, animation.morphAnimation!.numFrames,
animation.frameLengthInMs animation.morphAnimation!.frameLengthInMs
]); ]);
} }

View File

@@ -8,7 +8,7 @@ set(PROJECT_NAME "polyvox_filament")
project(${PROJECT_NAME}) project(${PROJECT_NAME})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -fPIC -Wno-unused-variable -Wno-unused-function") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -fPIC -Wno-unused-variable -Wno-unused-function")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -Wno-unused-variable") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -Wno-unused-variable -Wno-unused-function")
# This value is used when generating builds using this plugin, so it must # This value is used when generating builds using this plugin, so it must
# not be changed. # not be changed.

View File

@@ -21,11 +21,12 @@
#include "include/polyvox_filament/resource_loader.hpp" #include "include/polyvox_filament/resource_loader.hpp"
#include "FilamentViewer.hpp" #include "FilamentViewer.hpp"
#include "Log.hpp"
extern "C" { extern "C" {
#include "PolyvoxFilamentApi.h" #include "PolyvoxFilamentApi.h"
} }
#include <epoxy/gl.h> #include <epoxy/gl.h>
#include <epoxy/glx.h> #include <epoxy/glx.h>
@@ -63,7 +64,7 @@ static gboolean on_frame_tick(GtkWidget* widget, GdkFrameClock* frame_clock, gpo
static FlMethodResponse* _initialize(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { static FlMethodResponse* _initialize(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) {
if(self->_viewer) { if(self->_viewer) {
std::cout << "Deleting existing viewer"; Log("Deleting existing viewer");
filament_viewer_delete(self->_viewer); filament_viewer_delete(self->_viewer);
} }
@@ -113,6 +114,17 @@ static FlMethodResponse* _loadSkybox(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* _loadIbl(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) {
FlValue* args = fl_method_call_get_args(method_call);
const gchar* path = fl_value_get_string(args);
load_ibl(self->_viewer, path);
g_autoptr(FlValue) result = fl_value_new_string("OK");
return FL_METHOD_RESPONSE(fl_method_success_response_new(result));
}
static FlMethodResponse* _removeSkybox(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { static FlMethodResponse* _removeSkybox(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) {
std::cout << "Removing skybox" << std::endl; std::cout << "Removing skybox" << std::endl;
remove_skybox(self->_viewer); remove_skybox(self->_viewer);
@@ -287,6 +299,16 @@ 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_camera(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 cameraName = fl_value_get_string(fl_value_get_list_value(args, 1)) ;
set_camera(self->_viewer, (void*)assetPtr, cameraName);
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) { 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);
auto x = (float)fl_value_get_float(fl_value_get_list_value(args, 0)); auto x = (float)fl_value_get_float(fl_value_get_list_value(args, 0));
@@ -363,10 +385,11 @@ static FlMethodResponse* _stop_animation(PolyvoxFilamentPlugin* self, FlMethodCa
static FlMethodResponse* _apply_weights(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { static FlMethodResponse* _apply_weights(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 weightsValue = fl_value_get_list_value(args, 1); auto entityName = fl_value_get_string(fl_value_get_list_value(args, 1));
auto weightsValue = fl_value_get_list_value(args, 2);
float* const weights = (float* const) fl_value_get_float32_list(weightsValue); float* const weights = (float* const) fl_value_get_float32_list(weightsValue);
size_t len = fl_value_get_length(weightsValue); size_t len = fl_value_get_length(weightsValue);
apply_weights(assetPtr, weights, (int)len); apply_weights(assetPtr, entityName, weights, (int)len);
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));
} }
@@ -374,17 +397,18 @@ static FlMethodResponse* _apply_weights(PolyvoxFilamentPlugin* self, FlMethodCal
static FlMethodResponse* _set_animation(PolyvoxFilamentPlugin* self, FlMethodCall* method_call) { static FlMethodResponse* _set_animation(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));
float* const morphData = (float* const) fl_value_get_float32_list(fl_value_get_list_value(args, 1));
int64_t numMorphWeights = fl_value_get_int(fl_value_get_list_value(args, 2));
FlValue* flBoneAnimations = fl_value_get_list_value(args, 3); const char* entityName = fl_value_get_string(fl_value_get_list_value(args, 1));
float* const morphData = (float* const) fl_value_get_float32_list(fl_value_get_list_value(args, 2));
int64_t numMorphWeights = fl_value_get_int(fl_value_get_list_value(args, 3));
FlValue* flBoneAnimations = fl_value_get_list_value(args, 4);
size_t numBoneAnimations = fl_value_get_length(flBoneAnimations); size_t numBoneAnimations = fl_value_get_length(flBoneAnimations);
vector<BoneAnimation> boneAnimations; vector<BoneAnimation> boneAnimations;
boneAnimations.resize(numBoneAnimations);
for(int i = 0; i < numBoneAnimations; i++) { for(int i = 0; i < numBoneAnimations; i++) {
@@ -394,12 +418,13 @@ static FlMethodResponse* _set_animation(PolyvoxFilamentPlugin* self, FlMethodCal
FlValue* flMeshNames = fl_value_get_list_value(flBoneAnimation, 1); 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)); float* const frameData = (float* const) fl_value_get_float32_list(fl_value_get_list_value(flBoneAnimation, 2));
Log("Framedata %f", frameData);
vector<const char*> boneNames; vector<const char*> boneNames;
boneNames.resize(fl_value_get_length(flBoneNames)); boneNames.resize(fl_value_get_length(flBoneNames));
for(int i=0; i < boneNames.size(); i++) { for(int i=0; i < boneNames.size(); i++) {
boneNames[i] = fl_value_get_string(fl_value_get_list_value(flBoneNames, i)) ; boneNames[i] = fl_value_get_string(fl_value_get_list_value(flBoneNames, i)) ;
std::cout << boneNames[i] << std::endl;
} }
vector<const char*> meshNames; vector<const char*> meshNames;
@@ -407,28 +432,34 @@ static FlMethodResponse* _set_animation(PolyvoxFilamentPlugin* self, FlMethodCal
for(int i=0; i < meshNames.size(); i++) { for(int i=0; i < meshNames.size(); i++) {
meshNames[i] = fl_value_get_string(fl_value_get_list_value(flMeshNames, i)); meshNames[i] = fl_value_get_string(fl_value_get_list_value(flMeshNames, i));
} }
const char** boneNamesPtr = (const char**)malloc(boneNames.size() * sizeof(char*));
memcpy((void*)boneNamesPtr, (void*)boneNames.data(), boneNames.size() * sizeof(char*));
auto meshNamesPtr = (const char**)malloc(meshNames.size() * sizeof(char*));
memcpy((void*)meshNamesPtr, (void*)meshNames.data(), meshNames.size() * sizeof(char*));
auto animation = BoneAnimation(); BoneAnimation animation {
animation.boneNames = (const char**)malloc(boneNames.size() * sizeof(char*)); .boneNames = boneNamesPtr,
memcpy(animation.boneNames, boneNames.data(), boneNames.size() * sizeof(char*)); .meshNames = meshNamesPtr,
animation.numBones = boneNames.size(); .data = frameData,
animation.meshNames = (const char**)malloc(meshNames.size() * sizeof(char*)); .numBones = boneNames.size(),
memcpy(animation.meshNames, meshNames.data(), meshNames.size() * sizeof(char*)); .numMeshTargets = meshNames.size()
animation.numMeshTargets = meshNames.size(); };
animation.data = frameData;
boneAnimations.push_back(animation);
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, 5));
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, 6));
auto boneAnimationsPointer = boneAnimations.data(); auto boneAnimationsPointer = boneAnimations.data();
auto boneAnimationsSize = boneAnimations.size(); auto boneAnimationsSize = boneAnimations.size();
set_animation( set_animation(
assetPtr, assetPtr,
entityName,
morphData, morphData,
numMorphWeights, numMorphWeights,
boneAnimationsPointer, boneAnimationsPointer,
@@ -501,6 +532,8 @@ static void polyvox_filament_plugin_handle_method_call(
response = _initialize(self, method_call); response = _initialize(self, method_call);
} else if(strcmp(method, "loadSkybox") == 0) { } else if(strcmp(method, "loadSkybox") == 0) {
response = _loadSkybox(self, method_call); response = _loadSkybox(self, method_call);
} else if(strcmp(method, "loadIbl") == 0) {
response = _loadIbl(self, method_call);
} else if(strcmp(method, "removeSkybox") == 0) { } else if(strcmp(method, "removeSkybox") == 0) {
response = _removeSkybox(self, method_call); response = _removeSkybox(self, method_call);
} else if(strcmp(method, "resize") == 0) { } else if(strcmp(method, "resize") == 0) {
@@ -541,6 +574,8 @@ static void polyvox_filament_plugin_handle_method_call(
response = _rotate_end(self, method_call); response = _rotate_end(self, method_call);
} else if(strcmp(method, "rotateUpdate") == 0) { } else if(strcmp(method, "rotateUpdate") == 0) {
response = _rotate_update(self, method_call); response = _rotate_update(self, method_call);
} else if(strcmp(method, "setCamera") == 0) {
response = _set_camera(self, method_call);
} else if(strcmp(method, "setCameraPosition") == 0) { } else if(strcmp(method, "setCameraPosition") == 0) {
response = _set_camera_position(self, method_call); response = _set_camera_position(self, method_call);
} else if(strcmp(method, "setCameraRotation") == 0) { } else if(strcmp(method, "setCameraRotation") == 0) {