restructure render loop to correct timings and expose FFI methods for setBoneTransform/setMorphWeights
This commit is contained in:
@@ -280,16 +280,6 @@ namespace polyvox
|
||||
return _assets[pos->second].asset;
|
||||
}
|
||||
|
||||
// vector<int> completedBoneAnimations;
|
||||
|
||||
// for (int i = completed.size() - 1; i >= 0; i--) {
|
||||
// auto completedAnimationIndex = completed[i];
|
||||
// if(asset.animations.mType == AnimationType::BONE) {
|
||||
// completedBoneAnimations.push_back()
|
||||
// }
|
||||
// (completedAnimationIndex);
|
||||
// }
|
||||
|
||||
void AssetManager::updateAnimations()
|
||||
{
|
||||
|
||||
@@ -390,10 +380,13 @@ namespace polyvox
|
||||
}
|
||||
}
|
||||
|
||||
// TODO - we really don't want to be looking up the bone index/entity by name every single frame
|
||||
// - could use findChildEntityByName
|
||||
// - or is it better to add an option for "streaming" mode where we can just return a reference to a mat4 and then update the values directly?
|
||||
bool AssetManager::setBoneTransform(EntityId entityId, const char *entityName, int32_t skinIndex, const char* boneName, math::mat4f localTransform)
|
||||
{
|
||||
|
||||
Log("Setting transform for bone %s/skin %d for mesh target %s", boneName, skinIndex, entityName);
|
||||
std::lock_guard lock(_animationMutex);
|
||||
|
||||
const auto &pos = _entityIdLookup.find(entityId);
|
||||
if (pos == _entityIdLookup.end())
|
||||
@@ -414,6 +407,11 @@ namespace polyvox
|
||||
|
||||
const auto &renderableInstance = rm.getInstance(entity);
|
||||
|
||||
if(!renderableInstance.isValid()) {
|
||||
Log("Invalid renderable");
|
||||
return false;
|
||||
}
|
||||
|
||||
TransformManager &transformManager = _engine->getTransformManager();
|
||||
|
||||
const auto &filamentInstance = sceneAsset.asset->getInstance();
|
||||
@@ -442,6 +440,7 @@ namespace polyvox
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
utils::Entity joint = filamentInstance->getJointsAt(skinIndex)[boneIndex];
|
||||
|
||||
if (joint.isNull())
|
||||
@@ -577,6 +576,28 @@ namespace polyvox
|
||||
count);
|
||||
}
|
||||
|
||||
utils::Entity AssetManager::findChildEntityByName(EntityId entityId, const char *entityName) {
|
||||
std::lock_guard lock(_animationMutex);
|
||||
|
||||
const auto &pos = _entityIdLookup.find(entityId);
|
||||
if (pos == _entityIdLookup.end())
|
||||
{
|
||||
Log("Couldn't find asset under specified entity id.");
|
||||
return utils::Entity();
|
||||
}
|
||||
SceneAsset &sceneAsset = _assets[pos->second];
|
||||
|
||||
const auto entity = findEntityByName(sceneAsset, entityName);
|
||||
|
||||
if(entity.isNull()) {
|
||||
Log("Failed to find entity %s.", entityName);
|
||||
}
|
||||
|
||||
return entity;
|
||||
|
||||
}
|
||||
|
||||
|
||||
utils::Entity AssetManager::findEntityByName(SceneAsset asset, const char *entityName)
|
||||
{
|
||||
utils::Entity entity;
|
||||
|
||||
@@ -962,6 +962,7 @@ namespace polyvox
|
||||
|
||||
double _elapsed = 0;
|
||||
int _frameCount = 0;
|
||||
int _skippedFrames = 0;
|
||||
|
||||
void FilamentViewer::render(
|
||||
uint64_t frameTimeInNanos,
|
||||
@@ -981,6 +982,7 @@ namespace polyvox
|
||||
// Log("1 sec average for asset animation update %f", _elapsed / 60);
|
||||
_elapsed = 0;
|
||||
_frameCount = 0;
|
||||
Log("Skipped frames : %d", _skippedFrames);
|
||||
}
|
||||
|
||||
Timer tmr;
|
||||
@@ -1023,6 +1025,8 @@ namespace polyvox
|
||||
}
|
||||
else
|
||||
{
|
||||
_skippedFrames++;
|
||||
|
||||
// std::cout << "Skipped" << std::endl;
|
||||
// skipped frame
|
||||
}
|
||||
|
||||
@@ -16,24 +16,36 @@ class RenderLoop {
|
||||
public:
|
||||
explicit RenderLoop() {
|
||||
_t = new std::thread([this]() {
|
||||
auto last = std::chrono::high_resolution_clock::now();
|
||||
while (!_stop) {
|
||||
{
|
||||
if (_rendering) {
|
||||
doRender();
|
||||
}
|
||||
}
|
||||
std::function<void()> task;
|
||||
{
|
||||
|
||||
auto now = std::chrono::high_resolution_clock::now();
|
||||
|
||||
float elapsed = float(std::chrono::duration_cast<std::chrono::milliseconds>(now - last).count());
|
||||
|
||||
while(elapsed < 3 * _frameIntervalInMilliseconds / 4) {
|
||||
|
||||
std::function<void()> task;
|
||||
std::unique_lock<std::mutex> lock(_access);
|
||||
if (_tasks.empty()) {
|
||||
_cond.wait_for(lock, std::chrono::duration<float, std::milli>(
|
||||
_frameIntervalInMilliseconds));
|
||||
_cond.wait_for(lock, std::chrono::duration<float, std::milli>(1));
|
||||
now = std::chrono::high_resolution_clock::now();
|
||||
elapsed = float(std::chrono::duration_cast<std::chrono::milliseconds>(now - last).count());
|
||||
continue;
|
||||
}
|
||||
task = std::move(_tasks.front());
|
||||
_tasks.pop_front();
|
||||
task();
|
||||
|
||||
now = std::chrono::high_resolution_clock::now();
|
||||
elapsed = float(std::chrono::duration_cast<std::chrono::milliseconds>(now - last).count());
|
||||
}
|
||||
task();
|
||||
|
||||
if (_rendering) {
|
||||
doRender();
|
||||
}
|
||||
|
||||
last = now;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -428,5 +440,29 @@ get_name_for_entity_ffi(void *const assetManager, const EntityId entityId) {
|
||||
return fut.get();
|
||||
}
|
||||
|
||||
void set_morph_target_weights_ffi(void *const assetManager,
|
||||
EntityId asset,
|
||||
const char *const entityName,
|
||||
const float *const morphData,
|
||||
int numWeights) {
|
||||
std::packaged_task<void()> lambda(
|
||||
[&] { return set_morph_target_weights(assetManager, asset, entityName, morphData, numWeights); });
|
||||
auto fut = _rl->add_task(lambda);
|
||||
fut.wait();
|
||||
}
|
||||
|
||||
FLUTTER_PLUGIN_EXPORT bool set_bone_transform_ffi(
|
||||
void *assetManager,
|
||||
EntityId asset,
|
||||
const char *entityName,
|
||||
const float *const transform,
|
||||
const char *boneName) {
|
||||
std::packaged_task<bool()> lambda(
|
||||
[&] { return set_bone_transform(assetManager, asset, entityName, transform, boneName); });
|
||||
auto fut = _rl->add_task(lambda);
|
||||
fut.wait();
|
||||
return fut.get();
|
||||
}
|
||||
|
||||
FLUTTER_PLUGIN_EXPORT void ios_dummy_ffi() { Log("Dummy called"); }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user