expose methods for getting bone names
This commit is contained in:
@@ -236,6 +236,15 @@ abstract class AbstractFilamentViewer {
|
|||||||
Future<List<String>> getMorphTargetNames(
|
Future<List<String>> getMorphTargetNames(
|
||||||
FilamentEntity entity, FilamentEntity childEntity);
|
FilamentEntity entity, FilamentEntity childEntity);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Gets the names of all bones for the armature at [skinIndex] under the specified [entity].
|
||||||
|
///
|
||||||
|
Future<List<String>> getBoneNames(
|
||||||
|
FilamentEntity entity, { int skinIndex = 0});
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Gets the names of all glTF animations embedded in the specified entity.
|
||||||
|
///
|
||||||
Future<List<String>> getAnimationNames(FilamentEntity entity);
|
Future<List<String>> getAnimationNames(FilamentEntity entity);
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -565,6 +565,27 @@ external double get_animation_duration(
|
|||||||
int index,
|
int index,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ffi.Native<ffi.Int Function(ffi.Pointer<ffi.Void>, EntityId, ffi.Int)>(
|
||||||
|
symbol: 'get_bone_count',
|
||||||
|
assetId: 'package:dart_filament/dart_filament.dart')
|
||||||
|
external int get_bone_count(
|
||||||
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
|
int assetEntity,
|
||||||
|
int skinIndex,
|
||||||
|
);
|
||||||
|
|
||||||
|
@ffi.Native<
|
||||||
|
ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId,
|
||||||
|
ffi.Pointer<ffi.Pointer<ffi.Char>>, ffi.Int)>(
|
||||||
|
symbol: 'get_bone_names',
|
||||||
|
assetId: 'package:dart_filament/dart_filament.dart')
|
||||||
|
external void get_bone_names(
|
||||||
|
ffi.Pointer<ffi.Void> sceneManager,
|
||||||
|
int assetEntity,
|
||||||
|
ffi.Pointer<ffi.Pointer<ffi.Char>> outPtr,
|
||||||
|
int skinIndex,
|
||||||
|
);
|
||||||
|
|
||||||
@ffi.Native<
|
@ffi.Native<
|
||||||
ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, EntityId,
|
ffi.Void Function(ffi.Pointer<ffi.Void>, EntityId, EntityId,
|
||||||
ffi.Pointer<ffi.Char>, ffi.Int)>(
|
ffi.Pointer<ffi.Char>, ffi.Int)>(
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'dart:ffi';
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
import 'package:animation_tools_dart/animation_tools_dart.dart';
|
||||||
|
import 'package:dart_filament/dart_filament/compatibility/native/compatibility.dart';
|
||||||
import 'package:dart_filament/dart_filament/entities/filament_entity.dart';
|
import 'package:dart_filament/dart_filament/entities/filament_entity.dart';
|
||||||
import 'package:dart_filament/dart_filament/entities/gizmo.dart';
|
import 'package:dart_filament/dart_filament/entities/gizmo.dart';
|
||||||
|
|
||||||
@@ -422,6 +423,23 @@ class FilamentViewer extends AbstractFilamentViewer {
|
|||||||
return names.cast<String>();
|
return names.cast<String>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<List<String>> getBoneNames(FilamentEntity entity,
|
||||||
|
{int skinIndex = 0}) async {
|
||||||
|
var count = get_bone_count(_sceneManager!, entity, skinIndex);
|
||||||
|
var out = allocator<Pointer<Char>>(count);
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
out[i] = allocator<Char>(255);
|
||||||
|
}
|
||||||
|
|
||||||
|
get_bone_names(_sceneManager!, entity, out, skinIndex);
|
||||||
|
var names = <String>[];
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
var namePtr = out[i];
|
||||||
|
names.add(namePtr.cast<Utf8>().toDartString());
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<String>> getAnimationNames(FilamentEntity entity) async {
|
Future<List<String>> getAnimationNames(FilamentEntity entity) async {
|
||||||
var animationCount = get_animation_count(_sceneManager!, entity);
|
var animationCount = get_animation_count(_sceneManager!, entity);
|
||||||
@@ -461,6 +479,14 @@ class FilamentViewer extends AbstractFilamentViewer {
|
|||||||
FilamentEntity entity, MorphAnimationData animation,
|
FilamentEntity entity, MorphAnimationData animation,
|
||||||
{List<String>? targetMeshNames}) async {
|
{List<String>? targetMeshNames}) async {
|
||||||
var meshNames = await getChildEntityNames(entity, renderableOnly: true);
|
var meshNames = await getChildEntityNames(entity, renderableOnly: true);
|
||||||
|
if (targetMeshNames != null) {
|
||||||
|
for (final targetMeshName in targetMeshNames) {
|
||||||
|
if (!meshNames.contains(targetMeshName)) {
|
||||||
|
throw Exception(
|
||||||
|
"Error: mesh ${targetMeshName} does not exist under the specified entity. Available meshes : ${meshNames}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var meshEntities = await getChildEntities(entity, true);
|
var meshEntities = await getChildEntities(entity, true);
|
||||||
|
|
||||||
@@ -481,6 +507,8 @@ class FilamentViewer extends AbstractFilamentViewer {
|
|||||||
|
|
||||||
var meshMorphTargets = await getMorphTargetNames(entity, meshEntity);
|
var meshMorphTargets = await getMorphTargetNames(entity, meshEntity);
|
||||||
|
|
||||||
|
print("Got mesh morph targets ${meshMorphTargets}");
|
||||||
|
|
||||||
var intersection = animation.morphTargets
|
var intersection = animation.morphTargets
|
||||||
.toSet()
|
.toSet()
|
||||||
.intersection(meshMorphTargets.toSet())
|
.intersection(meshMorphTargets.toSet())
|
||||||
@@ -488,7 +516,11 @@ class FilamentViewer extends AbstractFilamentViewer {
|
|||||||
|
|
||||||
if (intersection.isEmpty) {
|
if (intersection.isEmpty) {
|
||||||
throw Exception(
|
throw Exception(
|
||||||
"No morph targets specified in animation are present on mesh $meshName. If you weren't intending to animate every mesh, specify [targetMeshNames] when invoking this method.\nAnimation morph targets: ${animation.morphTargets}\nMesh morph targets ${meshMorphTargets}");
|
"""No morph targets specified in animation are present on mesh $meshName.
|
||||||
|
If you weren't intending to animate every mesh, specify [targetMeshNames] when invoking this method.
|
||||||
|
Animation morph targets: ${animation.morphTargets}\n
|
||||||
|
Mesh morph targets ${meshMorphTargets}
|
||||||
|
Child meshes: ${meshNames}""");
|
||||||
}
|
}
|
||||||
|
|
||||||
var indices =
|
var indices =
|
||||||
@@ -1168,6 +1200,4 @@ class FilamentViewer extends AbstractFilamentViewer {
|
|||||||
Future setPriority(FilamentEntity entityId, int priority) async {
|
Future setPriority(FilamentEntity entityId, int priority) async {
|
||||||
set_priority(_sceneManager!, entityId, priority);
|
set_priority(_sceneManager!, entityId, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -510,6 +510,19 @@ extern "C"
|
|||||||
strcpy(outPtr, name.c_str());
|
strcpy(outPtr, name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE int get_bone_count(void *sceneManager, EntityId assetEntity, int skinIndex) {
|
||||||
|
auto names = ((SceneManager *)sceneManager)->getBoneNames(assetEntity, skinIndex);
|
||||||
|
return names->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE void get_bone_names(void *sceneManager, EntityId assetEntity, const char** out, int skinIndex) {
|
||||||
|
auto names = ((SceneManager *)sceneManager)->getBoneNames(assetEntity, skinIndex);
|
||||||
|
|
||||||
|
for(int i = 0; i < names->size(); i++) {
|
||||||
|
memcpy((void*)out[i], names->at(i).c_str(), names->at(i).length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_KEEPALIVE int get_morph_target_name_count(void *sceneManager, EntityId assetEntity, EntityId childEntity)
|
EMSCRIPTEN_KEEPALIVE int get_morph_target_name_count(void *sceneManager, EntityId assetEntity, EntityId childEntity)
|
||||||
{
|
{
|
||||||
auto names = ((SceneManager *)sceneManager)->getMorphTargetNames(assetEntity, childEntity);
|
auto names = ((SceneManager *)sceneManager)->getMorphTargetNames(assetEntity, childEntity);
|
||||||
|
|||||||
@@ -1239,6 +1239,44 @@ namespace flutter_filament
|
|||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unique_ptr<vector<string>> SceneManager::getBoneNames(EntityId assetEntityId, int skinIndex) {
|
||||||
|
|
||||||
|
unique_ptr<std::vector<std::string>> names = std::make_unique<std::vector<std::string>>();
|
||||||
|
|
||||||
|
auto *instance = getInstanceByEntityId(assetEntityId);
|
||||||
|
|
||||||
|
if (!instance)
|
||||||
|
{
|
||||||
|
auto *asset = getAssetByEntityId(assetEntityId);
|
||||||
|
if (asset)
|
||||||
|
{
|
||||||
|
instance = asset->getInstance();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log("ERROR: failed to find instance for entity %d", assetEntityId);
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t skinCount = instance->getSkinCount();
|
||||||
|
|
||||||
|
if (skinCount > 1)
|
||||||
|
{
|
||||||
|
Log("WARNING - skin count > 1 not currently implemented. This will probably not work");
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t numJoints = instance->getJointCountAt(skinIndex);
|
||||||
|
auto joints = instance->getJointsAt(skinIndex);
|
||||||
|
for (int i = 0; i < numJoints; i++)
|
||||||
|
{
|
||||||
|
const char *jointName = _ncm->getName(_ncm->getInstance(joints[i]));
|
||||||
|
names->push_back(jointName);
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SceneManager::transformToUnitCube(EntityId entityId)
|
void SceneManager::transformToUnitCube(EntityId entityId)
|
||||||
{
|
{
|
||||||
const auto *instance = getInstanceByEntityId(entityId);
|
const auto *instance = getInstanceByEntityId(entityId);
|
||||||
|
|||||||
Reference in New Issue
Block a user