add getTargetNames method
This commit is contained in:
@@ -24,6 +24,7 @@ class _MyAppState extends State<MyApp> {
|
|||||||
bool _rotate = false;
|
bool _rotate = false;
|
||||||
int _primitiveIndex = 0;
|
int _primitiveIndex = 0;
|
||||||
double _weight = 0.0;
|
double _weight = 0.0;
|
||||||
|
List<String> _targets = [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -60,90 +61,95 @@ class _MyAppState extends State<MyApp> {
|
|||||||
},
|
},
|
||||||
child: Stack(children: [
|
child: Stack(children: [
|
||||||
FilamentWidget(controller: _filamentController),
|
FilamentWidget(controller: _filamentController),
|
||||||
Column(mainAxisSize: MainAxisSize.min, children: [
|
Column(
|
||||||
ElevatedButton(
|
mainAxisSize: MainAxisSize.min,
|
||||||
child: Text("initialize"),
|
children: [
|
||||||
onPressed: () {
|
ElevatedButton(
|
||||||
_filamentController.initialize(
|
child: Text("initialize"),
|
||||||
materialPath: "assets/compiled.mat");
|
onPressed: () async {
|
||||||
_filamentController.loadSkybox(
|
await _filamentController.loadSkybox(
|
||||||
"assets/default_env/default_env_skybox.ktx",
|
"assets/default_env/default_env_skybox.ktx",
|
||||||
"assets/default_env/default_env_ibl.ktx");
|
"assets/default_env/default_env_ibl.ktx");
|
||||||
_filamentController.loadGltf(
|
await _filamentController.loadGltf(
|
||||||
"assets/guy.gltf", "assets", "Material");
|
"assets/guy.gltf", "assets");
|
||||||
// _filamentController.createMorpher(
|
_targets = await _filamentController
|
||||||
// "CC_Base_Body.003", "CC_Base_Body.003",
|
.getTargetNames("CC_Base_Body.002");
|
||||||
// materialName: "Material");
|
setState(() {});
|
||||||
}),
|
|
||||||
// ElevatedButton(
|
// _filamentController.createMorpher(
|
||||||
// child: Text("load skybox"),
|
// "CC_Base_Body.003", "CC_Base_Body.003",
|
||||||
// onPressed: () {
|
// materialName: "Material");
|
||||||
// _filamentController.loadSkybox(
|
}),
|
||||||
// "assets/default_env/default_env_skybox.ktx",
|
// ElevatedButton(
|
||||||
// "assets/default_env/default_env_ibl.ktx");
|
// child: Text("load skybox"),
|
||||||
// }),
|
// onPressed: () {
|
||||||
// ElevatedButton(
|
// _filamentController.loadSkybox(
|
||||||
// child: Text("load gltf"),
|
// "assets/default_env/default_env_skybox.ktx",
|
||||||
// onPressed: () {
|
// "assets/default_env/default_env_ibl.ktx");
|
||||||
// _filamentController.loadGltf(
|
// }),
|
||||||
// "assets/guy.gltf", "assets", "Material");
|
// ElevatedButton(
|
||||||
// }),
|
// child: Text("load gltf"),
|
||||||
// ElevatedButton(
|
// onPressed: () {
|
||||||
// child: Text("create morpher"),
|
// _filamentController.loadGltf(
|
||||||
// onPressed: () {
|
// "assets/guy.gltf", "assets", "Material");
|
||||||
// _filamentController.createMorpher(
|
// }),
|
||||||
// "CC_Base_Body.003", "CC_Base_Body.003",
|
// ElevatedButton(
|
||||||
// materialName: "Material");
|
// child: Text("create morpher"),
|
||||||
// }),
|
// onPressed: () {
|
||||||
Row(children: [
|
// _filamentController.createMorpher(
|
||||||
Container(
|
// "CC_Base_Body.003", "CC_Base_Body.003",
|
||||||
padding: EdgeInsets.all(10),
|
// materialName: "Material");
|
||||||
color: Colors.white,
|
// }),
|
||||||
child: Text(_primitiveIndex.toString())),
|
Row(children: [
|
||||||
ElevatedButton(
|
Container(
|
||||||
child: Text("+"),
|
padding: EdgeInsets.all(10),
|
||||||
onPressed: () {
|
color: Colors.white,
|
||||||
setState(() {
|
child: Text(_primitiveIndex.toString())),
|
||||||
_primitiveIndex = min(_primitiveIndex + 1, 5);
|
ElevatedButton(
|
||||||
});
|
child: Text("+"),
|
||||||
}),
|
onPressed: () {
|
||||||
ElevatedButton(
|
setState(() {
|
||||||
child: Text("-"),
|
_primitiveIndex = min(_primitiveIndex + 1, 5);
|
||||||
onPressed: () {
|
});
|
||||||
setState(() {
|
}),
|
||||||
_primitiveIndex = max(_primitiveIndex - 1, 0);
|
ElevatedButton(
|
||||||
});
|
child: Text("-"),
|
||||||
}),
|
onPressed: () {
|
||||||
]),
|
setState(() {
|
||||||
Slider(
|
_primitiveIndex = max(_primitiveIndex - 1, 0);
|
||||||
min: 0,
|
});
|
||||||
max: 1,
|
}),
|
||||||
divisions: 10,
|
]),
|
||||||
value: _weight,
|
Slider(
|
||||||
onChanged: (v) {
|
min: 0,
|
||||||
setState(() {
|
max: 1,
|
||||||
_weight = v;
|
divisions: 10,
|
||||||
_filamentController.applyWeights(
|
value: _weight,
|
||||||
List.filled(255, _weight), _primitiveIndex.toInt());
|
onChanged: (v) {
|
||||||
print("Set $_primitiveIndex to $_weight");
|
setState(() {
|
||||||
});
|
_weight = v;
|
||||||
}),
|
_filamentController.applyWeights(
|
||||||
Row(children: [
|
List.filled(255, _weight),
|
||||||
Checkbox(
|
_primitiveIndex.toInt());
|
||||||
value: _rotate,
|
});
|
||||||
onChanged: (v) {
|
}),
|
||||||
setState(() {
|
Row(children: [
|
||||||
_rotate = v == true;
|
Checkbox(
|
||||||
});
|
value: _rotate,
|
||||||
}),
|
onChanged: (v) {
|
||||||
ElevatedButton(
|
setState(() {
|
||||||
onPressed: () => _filamentController.zoom(100.0),
|
_rotate = v == true;
|
||||||
child: Text("+")),
|
});
|
||||||
ElevatedButton(
|
}),
|
||||||
onPressed: () => _filamentController.zoom(-100.0),
|
ElevatedButton(
|
||||||
child: Text("-"))
|
onPressed: () => _filamentController.zoom(100.0),
|
||||||
]),
|
child: const Text("+")),
|
||||||
]),
|
ElevatedButton(
|
||||||
|
onPressed: () => _filamentController.zoom(-100.0),
|
||||||
|
child: const Text("-"))
|
||||||
|
]),
|
||||||
|
] +
|
||||||
|
_targets.map((t) => Text(t)).toList()),
|
||||||
])),
|
])),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -49,28 +49,4 @@ flutter:
|
|||||||
- assets/FlightHelmet/textures/
|
- assets/FlightHelmet/textures/
|
||||||
- assets/textures/
|
- assets/textures/
|
||||||
|
|
||||||
# An image asset can refer to one or more resolution-specific "variants", see
|
|
||||||
# https://flutter.dev/assets-and-images/#resolution-aware.
|
|
||||||
|
|
||||||
# For details regarding adding assets from package dependencies, see
|
|
||||||
# https://flutter.dev/assets-and-images/#from-packages
|
|
||||||
|
|
||||||
# To add custom fonts to your application, add a fonts section here,
|
|
||||||
# in this "flutter" section. Each entry in this list should have a
|
|
||||||
# "family" key with the font family name, and a "fonts" key with a
|
|
||||||
# list giving the asset and other descriptors for the font. For
|
|
||||||
# example:
|
|
||||||
# fonts:
|
|
||||||
# - family: Schyler
|
|
||||||
# fonts:
|
|
||||||
# - asset: fonts/Schyler-Regular.ttf
|
|
||||||
# - asset: fonts/Schyler-Italic.ttf
|
|
||||||
# style: italic
|
|
||||||
# - family: Trajan Pro
|
|
||||||
# fonts:
|
|
||||||
# - asset: fonts/TrajanPro.ttf
|
|
||||||
# - asset: fonts/TrajanPro_Bold.ttf
|
|
||||||
# weight: 700
|
|
||||||
#
|
|
||||||
# For details regarding fonts from package dependencies,
|
|
||||||
# see https://flutter.dev/custom-fonts/#from-packages
|
|
||||||
@@ -14,7 +14,7 @@ static const id VIEW_TYPE = @"mimetic.app/filament_view";
|
|||||||
- (mimetic::FilamentViewer*) _viewer;
|
- (mimetic::FilamentViewer*) _viewer;
|
||||||
- (mimetic::ResourceBuffer)loadResource:(const char* const)path;
|
- (mimetic::ResourceBuffer)loadResource:(const char* const)path;
|
||||||
- (void)freeResource:(void*)mem size:(size_t)size misc:(void*)misc;
|
- (void)freeResource:(void*)mem size:(size_t)size misc:(void*)misc;
|
||||||
|
- (void)ready;
|
||||||
- (instancetype)initWithController:(FilamentViewController*)controller
|
- (instancetype)initWithController:(FilamentViewController*)controller
|
||||||
registrar:(NSObject<FlutterPluginRegistrar>*)registrar
|
registrar:(NSObject<FlutterPluginRegistrar>*)registrar
|
||||||
viewId:(int64_t)viewId
|
viewId:(int64_t)viewId
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ static void* freeResourceGlobal(void* mem, size_t size, void* misc) {
|
|||||||
} else if([@"loadGltf" isEqualToString:call.method]) {
|
} else if([@"loadGltf" isEqualToString:call.method]) {
|
||||||
if(!_viewer)
|
if(!_viewer)
|
||||||
return;
|
return;
|
||||||
_viewer->loadGltf([call.arguments[0] UTF8String], [call.arguments[1] UTF8String], [call.arguments[2] UTF8String]);
|
_viewer->loadGltf([call.arguments[0] UTF8String], [call.arguments[1] UTF8String]);
|
||||||
result(@"OK");
|
result(@"OK");
|
||||||
} else if([@"panStart" isEqualToString:call.method]) {
|
} else if([@"panStart" isEqualToString:call.method]) {
|
||||||
if(!_viewer)
|
if(!_viewer)
|
||||||
@@ -85,6 +85,13 @@ static void* freeResourceGlobal(void* mem, size_t size, void* misc) {
|
|||||||
_viewer->manipulator->grabEnd();
|
_viewer->manipulator->grabEnd();
|
||||||
} else if([@"createMorpher" isEqualToString:call.method]) {
|
} else if([@"createMorpher" isEqualToString:call.method]) {
|
||||||
_viewer->createMorpher([call.arguments[0] UTF8String], [call.arguments[1] UTF8String],[call.arguments[2] UTF8String]);
|
_viewer->createMorpher([call.arguments[0] UTF8String], [call.arguments[1] UTF8String],[call.arguments[2] UTF8String]);
|
||||||
|
} else if([@"getTargetNames" isEqualToString:call.method]) {
|
||||||
|
mimetic::StringList list = _viewer->getTargetNames([call.arguments UTF8String]);
|
||||||
|
NSMutableArray* asArray = [NSMutableArray arrayWithCapacity:list.count];
|
||||||
|
for(int i = 0; i < list.count; i++) {
|
||||||
|
asArray[i] = [NSString stringWithFormat:@"%s", list.strings[i]];
|
||||||
|
}
|
||||||
|
result(asArray);
|
||||||
} else if([@"applyWeights" isEqualToString:call.method]) {
|
} else if([@"applyWeights" isEqualToString:call.method]) {
|
||||||
if(!_viewer)
|
if(!_viewer)
|
||||||
return;
|
return;
|
||||||
@@ -113,7 +120,7 @@ static void* freeResourceGlobal(void* mem, size_t size, void* misc) {
|
|||||||
NSString* nsPath = [[NSBundle mainBundle] pathForResource:key
|
NSString* nsPath = [[NSBundle mainBundle] pathForResource:key
|
||||||
ofType:nil];
|
ofType:nil];
|
||||||
if (![[NSFileManager defaultManager] fileExistsAtPath:nsPath]) {
|
if (![[NSFileManager defaultManager] fileExistsAtPath:nsPath]) {
|
||||||
NSLog(@"Error: no file exists at %@", nsPath);
|
NSLog(@"Error: no file exists at %@", p);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,4 +135,8 @@ static void* freeResourceGlobal(void* mem, size_t size, void* misc) {
|
|||||||
free(mem);
|
free(mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)ready {
|
||||||
|
[_channel invokeMethod:@"ready" arguments:nil];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
[_controller viewDidLoad];
|
[_controller viewDidLoad];
|
||||||
_layer = (__bridge_retained void*)[_view layer];
|
_layer = (__bridge_retained void*)[_view layer];
|
||||||
_handler = [[FilamentMethodCallHandler alloc] initWithController:_controller registrar:registrar viewId:viewId layer:_layer];
|
_handler = [[FilamentMethodCallHandler alloc] initWithController:_controller registrar:registrar viewId:viewId layer:_layer];
|
||||||
|
[_handler ready];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,21 +20,21 @@ A new flutter plugin project.
|
|||||||
s.static_framework = true
|
s.static_framework = true
|
||||||
|
|
||||||
# Flutter.framework does not contain a i386 slice.
|
# Flutter.framework does not contain a i386 slice.
|
||||||
s.xcconfig = {
|
s.user_target_xcconfig = {
|
||||||
'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
|
'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
|
||||||
'ALWAYS_SEARCH_USER_PATHS' => 'YES',
|
'ALWAYS_SEARCH_USER_PATHS' => 'YES',
|
||||||
'USER_HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/mimetic_filament/ios/include" "${PODS_ROOT}/../.symlinks/plugins/mimetic_filament/ios/src", "${PODS_ROOT}/../.symlinks/plugins/mimetic_filament/ios/morph"',
|
'USER_HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/mimetic_filament/ios/include" "${PODS_ROOT}/../.symlinks/plugins/mimetic_filament/ios/src", "${PODS_ROOT}/../.symlinks/plugins/mimetic_filament/ios/morph"',
|
||||||
'OTHER_CXXFLAGS' => '--std=c++17',
|
'OTHER_CXXFLAGS' => '--std=c++17 -fmodules -fcxx-modules',
|
||||||
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
|
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
|
||||||
#"CLANG_CXX_LIBRARY" => "libc++"
|
#"CLANG_CXX_LIBRARY" => "libc++"
|
||||||
}
|
}
|
||||||
s.pod_target_xcconfig = {
|
s.pod_target_xcconfig = {
|
||||||
'DEFINES_MODULE' => 'YES',
|
'DEFINES_MODULE' => 'YES',
|
||||||
'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386',
|
'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386',
|
||||||
'OTHER_CFLAGS' => '-fmodules -fcxx-modules',
|
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
|
||||||
#'OTHER_CXXFLAGS' => '--std=c++17',
|
'OTHER_CXXFLAGS' => '--std=c++17 -fmodules -fcxx-modules',
|
||||||
#"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
|
'USER_HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/mimetic_filament/ios/include" "${PODS_ROOT}/../.symlinks/plugins/mimetic_filament/ios/src", "${PODS_ROOT}/../.symlinks/plugins/mimetic_filament/ios/morph"',
|
||||||
#"CLANG_CXX_LIBRARY" => "libc++"
|
'ALWAYS_SEARCH_USER_PATHS' => 'YES',
|
||||||
}
|
}
|
||||||
s.swift_version = '5.0'
|
s.swift_version = '5.0'
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -98,13 +98,13 @@ FilamentViewer::FilamentViewer(
|
|||||||
|
|
||||||
_swapChain = _engine->createSwapChain(_layer);
|
_swapChain = _engine->createSwapChain(_layer);
|
||||||
|
|
||||||
if(shaderPath) {
|
if(shaderPath) {
|
||||||
ResourceBuffer rb = _loadResource(shaderPath);
|
ResourceBuffer rb = _loadResource(shaderPath);
|
||||||
_materialProvider = createGPUMorphShaderLoader(rb.data, rb.size, _engine);
|
_materialProvider = createGPUMorphShaderLoader(rb.data, rb.size, _engine);
|
||||||
// _freeResource((void*)rb.data, rb.size, nullptr);
|
// _freeResource((void*)rb.data, rb.size, nullptr); <- TODO this is being freed too early, need to pass to callback?
|
||||||
} else {
|
} else {
|
||||||
_materialProvider = createUbershaderLoader(_engine);
|
_materialProvider = createUbershaderLoader(_engine);
|
||||||
}
|
}
|
||||||
EntityManager& em = EntityManager::get();
|
EntityManager& em = EntityManager::get();
|
||||||
_ncm = new NameComponentManager(em);
|
_ncm = new NameComponentManager(em);
|
||||||
_assetLoader = AssetLoader::create({_engine, _materialProvider, _ncm, &em});
|
_assetLoader = AssetLoader::create({_engine, _materialProvider, _ncm, &em});
|
||||||
@@ -113,7 +113,6 @@ FilamentViewer::FilamentViewer(
|
|||||||
|
|
||||||
manipulator =
|
manipulator =
|
||||||
Manipulator<float>::Builder().orbitHomePosition(0.0f, 0.0f, 0.0f).targetPosition(0.0f, 0.0f, 0).build(Mode::ORBIT);
|
Manipulator<float>::Builder().orbitHomePosition(0.0f, 0.0f, 0.0f).targetPosition(0.0f, 0.0f, 0).build(Mode::ORBIT);
|
||||||
//Manipulator<float>::Builder().orbitHomePosition(0.0f, 0.0f, 0.0f).targetPosition(0.0f, 0.0f, 0).build(Mode::ORBIT);
|
|
||||||
_asset = nullptr;
|
_asset = nullptr;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -143,12 +142,12 @@ void FilamentViewer::loadResources(string relativeResourcePath) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_animator = _asset->getAnimator();
|
_animator = _asset->getAnimator();
|
||||||
// _asset->releaseSourceData();
|
// _asset->releaseSourceData(); // we need to wait until the Morpher is created to release the source data
|
||||||
|
|
||||||
_scene->addEntities(_asset->getEntities(), _asset->getEntityCount());
|
_scene->addEntities(_asset->getEntities(), _asset->getEntityCount());
|
||||||
};
|
};
|
||||||
|
|
||||||
void FilamentViewer::loadGltf(const char* const uri, const char* const relativeResourcePath, const char* materialInstanceName) {
|
void FilamentViewer::loadGltf(const char* const uri, const char* const relativeResourcePath) {
|
||||||
if(_asset) {
|
if(_asset) {
|
||||||
_resourceLoader->evictResourceData();
|
_resourceLoader->evictResourceData();
|
||||||
_scene->removeEntities(_asset->getEntities(), _asset->getEntityCount());
|
_scene->removeEntities(_asset->getEntities(), _asset->getEntityCount());
|
||||||
@@ -162,7 +161,6 @@ void FilamentViewer::loadGltf(const char* const uri, const char* const relativeR
|
|||||||
// Parse the glTF file and create Filament entities.
|
// Parse the glTF file and create Filament entities.
|
||||||
_asset = _assetLoader->createAssetFromJson((uint8_t*)rbuf.data, rbuf.size);
|
_asset = _assetLoader->createAssetFromJson((uint8_t*)rbuf.data, rbuf.size);
|
||||||
|
|
||||||
|
|
||||||
if (!_asset) {
|
if (!_asset) {
|
||||||
std::cerr << "Unable to parse asset" << std::endl;
|
std::cerr << "Unable to parse asset" << std::endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -178,6 +176,22 @@ void FilamentViewer::loadGltf(const char* const uri, const char* const relativeR
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StringList FilamentViewer::getTargetNames(const char* meshName) {
|
||||||
|
FFilamentAsset* asset = (FFilamentAsset*)_asset;
|
||||||
|
NodeMap &sourceNodes = asset->isInstanced() ? asset->mInstances[0]->nodeMap
|
||||||
|
: asset->mNodeMap;
|
||||||
|
|
||||||
|
for (auto pair : sourceNodes) {
|
||||||
|
cgltf_node const *node = pair.first;
|
||||||
|
cgltf_mesh const *mesh = node->mesh;
|
||||||
|
|
||||||
|
if (mesh && strcmp(meshName, mesh->name) == 0) {
|
||||||
|
return StringList((const char**)mesh->target_names, (int) mesh->target_names_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return StringList(nullptr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void FilamentViewer::createMorpher(const char* meshName, const char* entityName, const char* materialInstanceName) {
|
void FilamentViewer::createMorpher(const char* meshName, const char* entityName, const char* materialInstanceName) {
|
||||||
morphHelper = new gltfio::GPUMorphHelper((FFilamentAsset*)_asset, meshName, entityName, materialInstanceName);
|
morphHelper = new gltfio::GPUMorphHelper((FFilamentAsset*)_asset, meshName, entityName, materialInstanceName);
|
||||||
}
|
}
|
||||||
@@ -250,16 +264,16 @@ void FilamentViewer::render() {
|
|||||||
// Extract the camera basis from the helper and push it to the Filament camera.
|
// Extract the camera basis from the helper and push it to the Filament camera.
|
||||||
math::float3 eye, target, upward;
|
math::float3 eye, target, upward;
|
||||||
manipulator->getLookAt(&eye, &target, &upward);
|
manipulator->getLookAt(&eye, &target, &upward);
|
||||||
//std::cout << "eye " << eye[0] << " " << eye[1] << " " << eye[2] << " " << target[0] << " " << target[1] << " " << target[2] << std::endl;
|
|
||||||
_mainCamera->lookAt(eye, target, upward);
|
_mainCamera->lookAt(eye, target, upward);
|
||||||
|
|
||||||
if(_animator) {
|
if(_animator) {
|
||||||
/*typedef std::chrono::duration<float, std::milli> duration;
|
typedef std::chrono::duration<float, std::milli> duration;
|
||||||
duration dur = std::chrono::high_resolution_clock::now() - startTime;
|
duration dur = std::chrono::high_resolution_clock::now() - startTime;
|
||||||
if (_animator->getAnimationCount() > 0) {
|
//if (_animator->getAnimationCount() > 0) {
|
||||||
_animator->applyAnimation(0, dur.count() / 1000);
|
///_animator->applyAnimation(0, dur.count() / 1000);
|
||||||
}
|
//}
|
||||||
_animator->updateBoneMatrices(); */
|
//_animator->updateBoneMatrices();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the scene, unless the renderer wants to skip the frame.
|
// Render the scene, unless the renderer wants to skip the frame.
|
||||||
|
|||||||
@@ -42,6 +42,12 @@ using namespace camutils;
|
|||||||
|
|
||||||
namespace mimetic {
|
namespace mimetic {
|
||||||
|
|
||||||
|
struct StringList {
|
||||||
|
StringList(const char** strings, const int count) : strings(strings), count(count) {};
|
||||||
|
const char** strings;
|
||||||
|
const int count;
|
||||||
|
};
|
||||||
|
|
||||||
struct ResourceBuffer {
|
struct ResourceBuffer {
|
||||||
ResourceBuffer(const void* data, const uint32_t size) : data(data), size(size) {};
|
ResourceBuffer(const void* data, const uint32_t size) : data(data), size(size) {};
|
||||||
const void* data;
|
const void* data;
|
||||||
@@ -55,11 +61,12 @@ namespace mimetic {
|
|||||||
public:
|
public:
|
||||||
FilamentViewer(void* layer, const char* shaderPath, LoadResource loadResource, FreeResource freeResource);
|
FilamentViewer(void* layer, const char* shaderPath, LoadResource loadResource, FreeResource freeResource);
|
||||||
~FilamentViewer();
|
~FilamentViewer();
|
||||||
void loadGltf(const char* const uri, const char* relativeResourcePath, const char* materialInstanceName);
|
void loadGltf(const char* const uri, const char* relativeResourcePath);
|
||||||
void loadSkybox(const char* const skyboxUri, const char* const iblUri);
|
void loadSkybox(const char* const skyboxUri, const char* const iblUri);
|
||||||
void updateViewportAndCameraProjection(int height, int width, float scaleFactor);
|
void updateViewportAndCameraProjection(int height, int width, float scaleFactor);
|
||||||
void render();
|
void render();
|
||||||
void createMorpher(const char* meshName, const char* entityName, const char* materialInstanceName);
|
void createMorpher(const char* meshName, const char* entityName, const char* materialInstanceName);
|
||||||
|
StringList getTargetNames(const char* meshName);
|
||||||
Manipulator<float>* manipulator;
|
Manipulator<float>* manipulator;
|
||||||
GPUMorphHelper* morphHelper;
|
GPUMorphHelper* morphHelper;
|
||||||
|
|
||||||
@@ -68,6 +75,7 @@ namespace mimetic {
|
|||||||
void transformToUnitCube();
|
void transformToUnitCube();
|
||||||
void cleanup();
|
void cleanup();
|
||||||
void* _layer;
|
void* _layer;
|
||||||
|
|
||||||
|
|
||||||
LoadResource _loadResource;
|
LoadResource _loadResource;
|
||||||
FreeResource _freeResource;
|
FreeResource _freeResource;
|
||||||
|
|||||||
@@ -70,10 +70,8 @@ namespace gltfio {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createTextures();
|
createTextures();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GPUMorphHelper::~GPUMorphHelper() {
|
GPUMorphHelper::~GPUMorphHelper() {
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
abstract class FilamentController {
|
abstract class FilamentController {
|
||||||
void onFilamentViewCreated(int id);
|
void onFilamentViewCreated(int id);
|
||||||
Future initialize({String? materialPath});
|
|
||||||
Future loadSkybox(String skyboxPath, String lightingPath);
|
Future loadSkybox(String skyboxPath, String lightingPath);
|
||||||
Future loadGlb(String path);
|
Future loadGlb(String path);
|
||||||
Future loadGltf(
|
Future loadGltf(String path, String relativeResourcePath);
|
||||||
String path, String relativeResourcePath, String materialInstanceName);
|
|
||||||
Future panStart(double x, double y);
|
Future panStart(double x, double y);
|
||||||
Future panUpdate(double x, double y);
|
Future panUpdate(double x, double y);
|
||||||
Future panEnd();
|
Future panEnd();
|
||||||
@@ -14,6 +15,10 @@ abstract class FilamentController {
|
|||||||
Future rotateUpdate(double x, double y);
|
Future rotateUpdate(double x, double y);
|
||||||
Future rotateEnd();
|
Future rotateEnd();
|
||||||
Future applyWeights(List<double> weights, int primitiveIndex);
|
Future applyWeights(List<double> weights, int primitiveIndex);
|
||||||
|
Future<List<String>> getTargetNames(String meshName);
|
||||||
|
|
||||||
|
void animate(
|
||||||
|
List<List<double>> weights, int primitiveIndex, double frameRate);
|
||||||
Future createMorpher(String meshName, String entityName,
|
Future createMorpher(String meshName, String entityName,
|
||||||
{String? materialName});
|
{String? materialName});
|
||||||
Future zoom(double z);
|
Future zoom(double z);
|
||||||
@@ -22,15 +27,27 @@ abstract class FilamentController {
|
|||||||
class MimeticFilamentController extends FilamentController {
|
class MimeticFilamentController extends FilamentController {
|
||||||
late int _id;
|
late int _id;
|
||||||
late MethodChannel _channel;
|
late MethodChannel _channel;
|
||||||
|
final String materialPath;
|
||||||
|
|
||||||
|
MimeticFilamentController(
|
||||||
|
{this.materialPath = "packages/mimetic_filament/assets/compiled.mat"});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onFilamentViewCreated(int id) async {
|
void onFilamentViewCreated(int id) async {
|
||||||
_id = id;
|
_id = id;
|
||||||
_channel = MethodChannel("mimetic.app/filament_view_$id");
|
_channel = MethodChannel("mimetic.app/filament_view_$id");
|
||||||
|
_channel.setMethodCallHandler((call) async {
|
||||||
|
await Future.delayed(Duration(
|
||||||
|
seconds:
|
||||||
|
1)); // todo - need a better way to know when the GL context is actaully ready
|
||||||
|
await _initialize();
|
||||||
|
return Future.value(true);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future initialize({String? materialPath}) async {
|
Future _initialize() async {
|
||||||
|
print("Initializing");
|
||||||
await _channel.invokeMethod("initialize", materialPath);
|
await _channel.invokeMethod("initialize", materialPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,10 +60,10 @@ class MimeticFilamentController extends FilamentController {
|
|||||||
throw Exception();
|
throw Exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future loadGltf(String path, String relativeResourcePath,
|
Future loadGltf(String path, String relativeResourcePath) async {
|
||||||
String materialInstanceName) async {
|
print(
|
||||||
await _channel.invokeMethod(
|
"Loading GLTF at $path with relative resource path $relativeResourcePath");
|
||||||
"loadGltf", [path, relativeResourcePath, materialInstanceName]);
|
await _channel.invokeMethod("loadGltf", [path, relativeResourcePath]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future panStart(double x, double y) async {
|
Future panStart(double x, double y) async {
|
||||||
@@ -77,6 +94,26 @@ class MimeticFilamentController extends FilamentController {
|
|||||||
await _channel.invokeMethod("applyWeights", [weights, primitiveIndex]);
|
await _channel.invokeMethod("applyWeights", [weights, primitiveIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<List<String>> getTargetNames(String meshName) async {
|
||||||
|
var result = (await _channel.invokeMethod("getTargetNames", meshName))
|
||||||
|
.cast<String>();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void animate(
|
||||||
|
List<List<double>> weights, int primitiveIndex, double frameRate) async {
|
||||||
|
final msPerFrame = 1000 ~/ frameRate;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
Timer.periodic(Duration(milliseconds: msPerFrame), (t) async {
|
||||||
|
_channel.invokeMethod("applyWeights", [weights[i], primitiveIndex]);
|
||||||
|
i++;
|
||||||
|
if (i >= weights.length) {
|
||||||
|
t.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Future zoom(double z) async {
|
Future zoom(double z) async {
|
||||||
await _channel.invokeMethod("zoom", z);
|
await _channel.invokeMethod("zoom", z);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
|
|
||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
|
|
||||||
class MimeticFilament {
|
|
||||||
static const MethodChannel _channel = MethodChannel('mimetic_filament');
|
|
||||||
|
|
||||||
static Future<String?> get platformVersion async {
|
|
||||||
final String? version = await _channel.invokeMethod('getPlatformVersion');
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
// You have generated a new plugin project without
|
|
||||||
// specifying the `--platforms` flag. A plugin project supports no platforms is generated.
|
|
||||||
// To add platforms, run `flutter create -t plugin --platforms <platforms> .` under the same
|
|
||||||
// directory. You can also find a detailed instruction on how to add platforms in the `pubspec.yaml` at https://flutter.dev/docs/development/packages-and-plugins/developing-packages#plugin-platforms.
|
|
||||||
|
|
||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
|
|
||||||
class MimeticFilamentPlugin {
|
|
||||||
static const MethodChannel _channel = MethodChannel('mimetic_filament');
|
|
||||||
|
|
||||||
static Future<String?> get platformVersion async {
|
|
||||||
final String? version = await _channel.invokeMethod('getPlatformVersion');
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void initialize() {}
|
|
||||||
}
|
|
||||||
@@ -20,6 +20,8 @@ dev_dependencies:
|
|||||||
flutter_lints: ^1.0.0
|
flutter_lints: ^1.0.0
|
||||||
|
|
||||||
flutter:
|
flutter:
|
||||||
|
assets:
|
||||||
|
- assets/compiled.mat
|
||||||
plugin:
|
plugin:
|
||||||
platforms:
|
platforms:
|
||||||
#android:
|
#android:
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
import 'package:mimetic_filament/mimetic_filament.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
const MethodChannel channel = MethodChannel('mimetic_filament');
|
|
||||||
|
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
|
||||||
|
|
||||||
setUp(() {
|
|
||||||
channel.setMockMethodCallHandler((MethodCall methodCall) async {
|
|
||||||
return '42';
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
tearDown(() {
|
|
||||||
channel.setMockMethodCallHandler(null);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('getPlatformVersion', () async {
|
|
||||||
expect(await MimeticAvatar.platformVersion, '42');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,23 +1,10 @@
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:mimetic_filament/mimetic_filament.dart';
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
const MethodChannel channel = MethodChannel('mimetic_filament');
|
const MethodChannel channel = MethodChannel('mimetic_filament');
|
||||||
|
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
setUp(() {
|
test('getPlatformVersion', () async {});
|
||||||
channel.setMockMethodCallHandler((MethodCall methodCall) async {
|
|
||||||
return '42';
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
tearDown(() {
|
|
||||||
channel.setMockMethodCallHandler(null);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('getPlatformVersion', () async {
|
|
||||||
expect(await MimeticFilament.platformVersion, '42');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user