tidy up method call handler and add example project with camera panning
This commit is contained in:
@@ -310,6 +310,7 @@
|
|||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEAD_CODE_STRIPPING = NO;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
@@ -324,6 +325,7 @@
|
|||||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
STRIP_INSTALLED_PRODUCT = NO;
|
||||||
SUPPORTED_PLATFORMS = iphoneos;
|
SUPPORTED_PLATFORMS = iphoneos;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VALIDATE_PRODUCT = YES;
|
VALIDATE_PRODUCT = YES;
|
||||||
@@ -337,6 +339,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
|
DEAD_CODE_STRIPPING = NO;
|
||||||
DEVELOPMENT_TEAM = 873X6R39HP;
|
DEVELOPMENT_TEAM = 873X6R39HP;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp;
|
GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp;
|
||||||
@@ -345,8 +348,10 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
|
PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.mimeticAvatarExample;
|
PRODUCT_BUNDLE_IDENTIFIER = com.example.mimeticAvatarExample;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
STRIP_INSTALLED_PRODUCT = NO;
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
@@ -383,6 +388,7 @@
|
|||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEAD_CODE_STRIPPING = NO;
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
@@ -404,6 +410,7 @@
|
|||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
STRIP_INSTALLED_PRODUCT = NO;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
@@ -438,6 +445,7 @@
|
|||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEAD_CODE_STRIPPING = NO;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
@@ -452,6 +460,7 @@
|
|||||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
STRIP_INSTALLED_PRODUCT = NO;
|
||||||
SUPPORTED_PLATFORMS = iphoneos;
|
SUPPORTED_PLATFORMS = iphoneos;
|
||||||
SWIFT_COMPILATION_MODE = wholemodule;
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||||
@@ -467,6 +476,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
|
DEAD_CODE_STRIPPING = NO;
|
||||||
DEVELOPMENT_TEAM = 873X6R39HP;
|
DEVELOPMENT_TEAM = 873X6R39HP;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp;
|
GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp;
|
||||||
@@ -475,8 +485,10 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
|
PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.mimeticAvatarExample;
|
PRODUCT_BUNDLE_IDENTIFIER = com.example.mimeticAvatarExample;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
STRIP_INSTALLED_PRODUCT = NO;
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
@@ -491,6 +503,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
|
DEAD_CODE_STRIPPING = NO;
|
||||||
DEVELOPMENT_TEAM = 873X6R39HP;
|
DEVELOPMENT_TEAM = 873X6R39HP;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp;
|
GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp;
|
||||||
@@ -499,8 +512,10 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
|
PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.mimeticAvatarExample;
|
PRODUCT_BUNDLE_IDENTIFIER = com.example.mimeticAvatarExample;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
STRIP_INSTALLED_PRODUCT = NO;
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ class MyApp extends StatefulWidget {
|
|||||||
|
|
||||||
class _MyAppState extends State<MyApp> {
|
class _MyAppState extends State<MyApp> {
|
||||||
final FilamentController _filamentController = MimeticFilamentController();
|
final FilamentController _filamentController = MimeticFilamentController();
|
||||||
String _platformVersion = 'Unknown';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -32,23 +31,44 @@ class _MyAppState extends State<MyApp> {
|
|||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('Plugin example app'),
|
title: const Text('Plugin example app'),
|
||||||
),
|
),
|
||||||
body: Stack(children: [
|
body: GestureDetector(
|
||||||
FilamentWidget(controller: _filamentController),
|
behavior: HitTestBehavior.opaque,
|
||||||
Column(children: [
|
onPanDown: (details) {
|
||||||
ElevatedButton(
|
_filamentController.panStart(
|
||||||
child: Text("initialize"),
|
details.localPosition.dx, details.localPosition.dy);
|
||||||
onPressed: () {
|
},
|
||||||
_filamentController.initialize();
|
onPanUpdate: (details) {
|
||||||
}),
|
print(details.localPosition.dx);
|
||||||
ElevatedButton(
|
_filamentController.panUpdate(
|
||||||
child: Text("load asset"),
|
details.localPosition.dx, details.localPosition.dy);
|
||||||
onPressed: () {
|
},
|
||||||
_filamentController.loadSkybox(
|
onPanEnd: (d) {
|
||||||
"assets/default_env/default_env_skybox.ktx",
|
_filamentController.panEnd();
|
||||||
"assets/default_env/default_env_ibl.ktx");
|
},
|
||||||
}),
|
child: Stack(children: [
|
||||||
]),
|
FilamentWidget(controller: _filamentController),
|
||||||
]),
|
Column(children: [
|
||||||
|
ElevatedButton(
|
||||||
|
child: Text("initialize"),
|
||||||
|
onPressed: () {
|
||||||
|
_filamentController.initialize();
|
||||||
|
}),
|
||||||
|
ElevatedButton(
|
||||||
|
child: Text("load skybox"),
|
||||||
|
onPressed: () {
|
||||||
|
_filamentController.loadSkybox(
|
||||||
|
"assets/default_env/default_env_skybox.ktx",
|
||||||
|
"assets/default_env/default_env_ibl.ktx");
|
||||||
|
}),
|
||||||
|
ElevatedButton(
|
||||||
|
child: Text("load gltf"),
|
||||||
|
onPressed: () {
|
||||||
|
_filamentController.loadGltf(
|
||||||
|
"assets/BusterDrone/scene.gltf",
|
||||||
|
"assets/BusterDrone");
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
])),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,16 +39,14 @@ dev_dependencies:
|
|||||||
|
|
||||||
# The following section is specific to Flutter.
|
# The following section is specific to Flutter.
|
||||||
flutter:
|
flutter:
|
||||||
|
|
||||||
# The following line ensures that the Material Icons font is
|
|
||||||
# included with your application, so that you can use the icons in
|
|
||||||
# the material Icons class.
|
|
||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
|
assets:
|
||||||
# To add assets to your application, add an assets section, like this:
|
- assets/
|
||||||
# assets:
|
- assets/default_env/
|
||||||
# - images/a_dot_burr.jpeg
|
- assets/BusterDrone/
|
||||||
# - images/a_dot_ham.jpeg
|
- assets/BusterDrone/textures/
|
||||||
|
- assets/FlightHelmet/
|
||||||
|
- assets/FlightHelmet/textures/
|
||||||
|
|
||||||
# An image asset can refer to one or more resolution-specific "variants", see
|
# An image asset can refer to one or more resolution-specific "variants", see
|
||||||
# https://flutter.dev/assets-and-images/#resolution-aware.
|
# https://flutter.dev/assets-and-images/#resolution-aware.
|
||||||
|
|||||||
23
ios/Classes/filament/FilamentMethodCallHandler.h
Normal file
23
ios/Classes/filament/FilamentMethodCallHandler.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef FilamentMethodCallHandler_h
|
||||||
|
#define FilamentMethodCallHandler_h
|
||||||
|
#endif /* FilamentNativeViewFactory_h */
|
||||||
|
|
||||||
|
#import <Flutter/Flutter.h>
|
||||||
|
#import "FilamentViewController.h"
|
||||||
|
|
||||||
|
#include "FilamentViewer.hpp"
|
||||||
|
|
||||||
|
static const id VIEW_TYPE = @"mimetic.app/filament_view";
|
||||||
|
|
||||||
|
@interface FilamentMethodCallHandler : FlutterMethodChannel
|
||||||
|
- (void)handleMethodCall:(FlutterMethodCall* _Nonnull)call result:( FlutterResult _Nonnull)result;
|
||||||
|
- (mimetic::FilamentViewer*) _viewer;
|
||||||
|
- (mimetic::ResourceBuffer)loadResource:(const char* const)path;
|
||||||
|
- (void)freeResource:(void*)mem size:(size_t)size misc:(void*)misc;
|
||||||
|
|
||||||
|
- (instancetype)initWithController:(FilamentViewController*)controller
|
||||||
|
registrar:(NSObject<FlutterPluginRegistrar>*)registrar
|
||||||
|
viewId:(int64_t)viewId
|
||||||
|
layer:(void*)layer;
|
||||||
|
|
||||||
|
@end
|
||||||
97
ios/Classes/filament/FilamentMethodCallHandler.mm
Normal file
97
ios/Classes/filament/FilamentMethodCallHandler.mm
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
#import "FilamentMethodCallHandler.h"
|
||||||
|
#import "FilamentViewController.h"
|
||||||
|
#import "FilamentNativeViewFactory.h"
|
||||||
|
|
||||||
|
static const FilamentMethodCallHandler* _handler;
|
||||||
|
|
||||||
|
static mimetic::ResourceBuffer loadResourceGlobal(const char* name) {
|
||||||
|
return [_handler loadResource:name];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* freeResourceGlobal(void* mem, size_t size, void* misc) {
|
||||||
|
[_handler freeResource:mem size:size misc:misc ];
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
@implementation FilamentMethodCallHandler {
|
||||||
|
FilamentViewController *_controller;
|
||||||
|
FlutterMethodChannel* _channel;
|
||||||
|
mimetic::FilamentViewer* _viewer;
|
||||||
|
void* _layer;
|
||||||
|
|
||||||
|
NSObject<FlutterPluginRegistrar>* _registrar;
|
||||||
|
}
|
||||||
|
- (instancetype)initWithController:(FilamentViewController*)controller
|
||||||
|
registrar:(NSObject<FlutterPluginRegistrar>*)registrar
|
||||||
|
viewId:(int64_t)viewId
|
||||||
|
layer:(void*)layer
|
||||||
|
{
|
||||||
|
_layer = layer;
|
||||||
|
_registrar = registrar;
|
||||||
|
_controller = controller;
|
||||||
|
NSString* channelName = [NSString stringWithFormat:@"%@_%d",VIEW_TYPE,viewId];
|
||||||
|
_channel = [FlutterMethodChannel
|
||||||
|
methodChannelWithName:channelName
|
||||||
|
binaryMessenger:[registrar messenger]];
|
||||||
|
[_channel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
|
||||||
|
[self handleMethodCall:call result:result];
|
||||||
|
}];
|
||||||
|
_handler = self;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)handleMethodCall:(FlutterMethodCall* _Nonnull)call result:(FlutterResult _Nonnull )result {
|
||||||
|
if([@"initialize" isEqualToString:call.method]) {
|
||||||
|
_viewer = new mimetic::FilamentViewer(_layer, loadResourceGlobal, freeResourceGlobal);
|
||||||
|
[_controller setViewer:_viewer];
|
||||||
|
[_controller startDisplayLink];
|
||||||
|
result(@"OK");
|
||||||
|
} else if([@"loadSkybox" isEqualToString:call.method]) {
|
||||||
|
if(!_viewer)
|
||||||
|
return;
|
||||||
|
_viewer->loadSkybox([call.arguments[0] UTF8String], [call.arguments[1] UTF8String]);
|
||||||
|
result(@"OK");
|
||||||
|
} else if([@"loadGltf" isEqualToString:call.method]) {
|
||||||
|
if(!_viewer)
|
||||||
|
return;
|
||||||
|
_viewer->loadGltf([call.arguments[0] UTF8String], [call.arguments[1] UTF8String]);
|
||||||
|
result(@"OK");
|
||||||
|
} else if([@"panStart" isEqualToString:call.method]) {
|
||||||
|
if(!_viewer)
|
||||||
|
return;
|
||||||
|
_viewer->manipulator->grabBegin([call.arguments[0] intValue], [call.arguments[1] intValue], true);
|
||||||
|
} else if([@"panUpdate" isEqualToString:call.method]) {
|
||||||
|
if(!_viewer)
|
||||||
|
return;
|
||||||
|
_viewer->manipulator->grabUpdate([call.arguments[0] intValue], [call.arguments[1] intValue]);
|
||||||
|
} else if([@"panEnd" isEqualToString:call.method]) {
|
||||||
|
if(!_viewer)
|
||||||
|
return;
|
||||||
|
_viewer->manipulator->grabEnd();
|
||||||
|
} else {
|
||||||
|
result(FlutterMethodNotImplemented);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (mimetic::ResourceBuffer)loadResource:(const char* const)path {
|
||||||
|
NSString* p = [NSString stringWithFormat:@"%s", path];
|
||||||
|
NSString* key = [_registrar lookupKeyForAsset:p];
|
||||||
|
NSString* nsPath = [[NSBundle mainBundle] pathForResource:key
|
||||||
|
ofType:nil];
|
||||||
|
if (![[NSFileManager defaultManager] fileExistsAtPath:nsPath]) {
|
||||||
|
NSLog(@"Error: no file exists at %@", nsPath);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
NSData* buffer = [NSData dataWithContentsOfFile:nsPath];
|
||||||
|
void* cpy = malloc([buffer length]);
|
||||||
|
memcpy(cpy, [buffer bytes], [buffer length]); // can we avoid this copy somehow?
|
||||||
|
mimetic::ResourceBuffer rbuf(cpy, [buffer length]);
|
||||||
|
return rbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)freeResource:(void*)mem size:(size_t)s misc:(void *)m {
|
||||||
|
free(mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -3,17 +3,13 @@
|
|||||||
#endif /* FilamentNativeViewFactory_h */
|
#endif /* FilamentNativeViewFactory_h */
|
||||||
|
|
||||||
#import <Flutter/Flutter.h>
|
#import <Flutter/Flutter.h>
|
||||||
#import "FilamentViewer.hpp"
|
#import "FilamentView.h"
|
||||||
|
|
||||||
|
#include "FilamentViewer.hpp"
|
||||||
|
|
||||||
@interface FilamentMethodCallHandler : FlutterMethodChannel
|
|
||||||
- (void)handleMethodCall:(FlutterMethodCall* _Nonnull)call result:( FlutterResult _Nonnull)result;
|
|
||||||
- (mimetic::FilamentViewer*) _viewer;
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface FilamentNativeViewFactory : NSObject <FlutterPlatformViewFactory>
|
@interface FilamentNativeViewFactory : NSObject <FlutterPlatformViewFactory>
|
||||||
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar;
|
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar;
|
||||||
- (mimetic::ResourceBuffer)loadResource:(const char* const)path;
|
|
||||||
- (void)freeResource:(void*)mem size:(size_t)size misc:(void*)misc;
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface FilamentNativeView : NSObject <FlutterPlatformView>
|
@interface FilamentNativeView : NSObject <FlutterPlatformView>
|
||||||
|
|||||||
@@ -1,18 +1,6 @@
|
|||||||
#import "FilamentNativeViewFactory.h"
|
#import "FilamentNativeViewFactory.h"
|
||||||
#import "FilamentViewController.h"
|
#import "FilamentViewController.h"
|
||||||
|
#import "FilamentMethodCallHandler.h"
|
||||||
static const id VIEW_TYPE = @"mimetic.app/filament_view";
|
|
||||||
|
|
||||||
static const FilamentNativeViewFactory* _factory;
|
|
||||||
|
|
||||||
static mimetic::ResourceBuffer loadResource(const char* const name) {
|
|
||||||
return [_factory loadResource:name];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void* freeResource(void* mem, size_t size, void* misc) {
|
|
||||||
[_factory freeResource:mem size:size misc:misc ];
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
@implementation FilamentNativeViewFactory {
|
@implementation FilamentNativeViewFactory {
|
||||||
NSObject<FlutterPluginRegistrar>* _registrar;
|
NSObject<FlutterPluginRegistrar>* _registrar;
|
||||||
@@ -23,7 +11,6 @@ static void* freeResource(void* mem, size_t size, void* misc) {
|
|||||||
if (self) {
|
if (self) {
|
||||||
_registrar = registrar;
|
_registrar = registrar;
|
||||||
}
|
}
|
||||||
_factory = self;
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,81 +25,27 @@ static void* freeResource(void* mem, size_t size, void* misc) {
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation FilamentMethodCallHandler {
|
|
||||||
FilamentViewController *_controller;
|
|
||||||
FlutterMethodChannel* _channel;
|
|
||||||
mimetic::FilamentViewer* _viewer;
|
|
||||||
void* _layer;
|
|
||||||
}
|
|
||||||
- (instancetype)initWithController:(FilamentViewController*)controller
|
|
||||||
registrar:(NSObject<FlutterPluginRegistrar>*)registrar
|
|
||||||
viewId:(int64_t)viewId
|
|
||||||
layer:(void*)layer
|
|
||||||
{
|
|
||||||
_layer = layer;
|
|
||||||
_controller = controller;
|
|
||||||
NSString* channelName = [NSString stringWithFormat:@"%@_%d",VIEW_TYPE,viewId];
|
|
||||||
_channel = [FlutterMethodChannel
|
|
||||||
methodChannelWithName:channelName
|
|
||||||
binaryMessenger:[registrar messenger]];
|
|
||||||
[_channel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
|
|
||||||
[self handleMethodCall:call result:result];
|
|
||||||
}];
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)handleMethodCall:(FlutterMethodCall* _Nonnull)call result:(FlutterResult _Nonnull )result {
|
|
||||||
if([@"initialize" isEqualToString:call.method]) {
|
|
||||||
[self initialize];
|
|
||||||
} else {
|
|
||||||
result(FlutterMethodNotImplemented);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (mimetic::ResourceBuffer)loadResource:(const char* const)path {
|
|
||||||
|
|
||||||
NSString* documentPath = [NSSearchPathForDirectoriesInDomains(
|
|
||||||
NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
|
|
||||||
NSString* pathComponent = [NSString stringWithUTF8String:path];
|
|
||||||
NSString* nsPath = [documentPath stringByAppendingPathComponent:pathComponent];
|
|
||||||
|
|
||||||
if (![[NSFileManager defaultManager] fileExistsAtPath:nsPath]) {
|
|
||||||
NSLog(@"Error: no file exists at %@", nsPath);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
NSData* buffer = [NSData dataWithContentsOfFile:nsPath];
|
|
||||||
|
|
||||||
mimetic::ResourceBuffer rbuf([buffer bytes], [buffer length]);
|
|
||||||
return rbuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)freeResource:(void*)mem size:(size_t)s misc:(void *)m {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
-(void)initialize {
|
|
||||||
_viewer = new mimetic::FilamentViewer(_layer, loadResource, freeResource);
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation FilamentNativeView {
|
@implementation FilamentNativeView {
|
||||||
FilamentView *_view;
|
FilamentView* _view;
|
||||||
FilamentViewController *_controller;
|
FilamentViewController* _controller;
|
||||||
FilamentMethodCallHandler *_handler;
|
mimetic::FilamentViewer* _viewer;
|
||||||
|
FilamentMethodCallHandler* _handler;
|
||||||
|
void* _layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (instancetype)initWithFrame:(CGRect)frame
|
- (instancetype)initWithFrame:(CGRect)frame
|
||||||
viewIdentifier:(int64_t)viewId
|
viewIdentifier:(int64_t)viewId
|
||||||
arguments:(id _Nullable)args
|
arguments:(id _Nullable)args
|
||||||
registrar:(NSObject<FlutterPluginRegistrar>*)registrar {
|
registrar:(NSObject<FlutterPluginRegistrar>*)registrar {
|
||||||
if (self = [super init]) {
|
if (self = [super init]) {
|
||||||
_view = [[FilamentView alloc] init];
|
_view = [[FilamentView alloc] init];
|
||||||
_controller = [[FilamentViewController alloc] initWithRegistrar:registrar];
|
_controller = [[FilamentViewController alloc] initWithRegistrar:registrar view:_view];
|
||||||
_controller.modelView = _view;
|
|
||||||
[_controller viewDidLoad];
|
[_controller viewDidLoad];
|
||||||
[_controller startDisplayLink];
|
_layer = (__bridge_retained void*)[_view layer];
|
||||||
_handler = [[FilamentMethodCallHandler alloc] initWithController:_controller registrar:registrar viewId:viewId layer:(__bridge void*)[_view layer]];
|
_handler = [[FilamentMethodCallHandler alloc] initWithController:_controller registrar:registrar viewId:viewId layer:_layer];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
#include "FilamentViewer.hpp"
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,8 +24,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@interface FilamentView : UIView
|
@interface FilamentView : UIView
|
||||||
|
- (void)setViewer:(mimetic::FilamentViewer*)viewer;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
|||||||
@@ -16,21 +16,26 @@
|
|||||||
|
|
||||||
// These defines are set in the "Preprocessor Macros" build setting for each scheme.
|
// These defines are set in the "Preprocessor Macros" build setting for each scheme.
|
||||||
#include "FilamentView.h"
|
#include "FilamentView.h"
|
||||||
|
#include "FilamentViewer.hpp"
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@interface FilamentView ()
|
@interface FilamentView ()
|
||||||
|
|
||||||
- (void)initCommon;
|
- (void)initCommon;
|
||||||
|
- (void)setViewer:(mimetic::FilamentViewer*)viewer;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation FilamentView {
|
@implementation FilamentView {
|
||||||
|
mimetic::FilamentViewer* _viewer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setViewer:(mimetic::FilamentViewer*)viewer {
|
||||||
|
_viewer = viewer;
|
||||||
|
_viewer->updateViewportAndCameraProjection(self.bounds.size.width, self.bounds.size.height, self.contentScaleFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
- (instancetype)initWithFrame:(CGRect)frame {
|
- (instancetype)initWithFrame:(CGRect)frame {
|
||||||
if (self = [super initWithFrame:frame]) {
|
if (self = [super initWithFrame:frame]) {
|
||||||
[self initCommon];
|
[self initCommon];
|
||||||
@@ -58,4 +63,18 @@ using namespace std;
|
|||||||
return [CAEAGLLayer class];
|
return [CAEAGLLayer class];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)layoutSubviews {
|
||||||
|
[super layoutSubviews];
|
||||||
|
if(_viewer) {
|
||||||
|
_viewer->updateViewportAndCameraProjection(self.bounds.size.width, self.bounds.size.height, self.contentScaleFactor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setContentScaleFactor:(CGFloat)contentScaleFactor {
|
||||||
|
[super setContentScaleFactor:contentScaleFactor];
|
||||||
|
if(_viewer) {
|
||||||
|
_viewer->updateViewportAndCameraProjection(self.bounds.size.width, self.bounds.size.height, self.contentScaleFactor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -18,14 +18,15 @@
|
|||||||
|
|
||||||
#import "FilamentView.h"
|
#import "FilamentView.h"
|
||||||
#import "Flutter/Flutter.h"
|
#import "Flutter/Flutter.h"
|
||||||
|
#import "FilamentViewer.hpp"
|
||||||
|
|
||||||
@interface FilamentViewController : UIViewController
|
@interface FilamentViewController : UIViewController
|
||||||
|
|
||||||
@property(weak, nonatomic) IBOutlet FilamentView* modelView;
|
@property(weak, nonatomic) IBOutlet FilamentView* modelView;
|
||||||
|
- (void)setViewer:(mimetic::FilamentViewer*)viewer;
|
||||||
- (void)startDisplayLink;
|
- (void)startDisplayLink;
|
||||||
- (void)stopDisplayLink;
|
- (void)stopDisplayLink;
|
||||||
|
|
||||||
-initWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar;
|
-initWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar view:(FilamentView*)view;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -16,20 +16,29 @@
|
|||||||
|
|
||||||
#import "FilamentViewController.h"
|
#import "FilamentViewController.h"
|
||||||
#import "FilamentView.h"
|
#import "FilamentView.h"
|
||||||
|
#import "FilamentViewer.hpp"
|
||||||
#import <Flutter/Flutter.h>
|
#import <Flutter/Flutter.h>
|
||||||
|
|
||||||
@implementation FilamentViewController {
|
@implementation FilamentViewController {
|
||||||
CADisplayLink* _displayLink;
|
CADisplayLink* _displayLink;
|
||||||
NSObject<FlutterPluginRegistrar>* _registrar;
|
NSObject<FlutterPluginRegistrar>* _registrar;
|
||||||
|
mimetic::FilamentViewer* _viewer;
|
||||||
|
FilamentView* _view;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
|
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar
|
||||||
|
view:(FilamentView*)view {
|
||||||
if (self = [super init]) {
|
if (self = [super init]) {
|
||||||
_registrar = registrar;
|
_registrar = registrar;
|
||||||
|
_view = view;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
- (void)setViewer:(mimetic::FilamentViewer*)viewer {
|
||||||
|
_viewer = viewer;
|
||||||
|
[_view setViewer:_viewer];
|
||||||
|
}
|
||||||
#pragma mark UIViewController methods
|
#pragma mark UIViewController methods
|
||||||
|
|
||||||
- (void)viewDidLoad {
|
- (void)viewDidLoad {
|
||||||
@@ -59,7 +68,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)render {
|
- (void)render {
|
||||||
|
if(_viewer) {
|
||||||
|
_viewer->render();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc {
|
- (void)dealloc {
|
||||||
|
|||||||
@@ -20,11 +20,16 @@ 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 = {
|
||||||
|
'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => '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"',
|
||||||
|
|
||||||
|
}
|
||||||
s.pod_target_xcconfig = {
|
s.pod_target_xcconfig = {
|
||||||
'DEFINES_MODULE' => 'YES',
|
'DEFINES_MODULE' => 'YES',
|
||||||
'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386',
|
'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386',
|
||||||
'ALWAYS_SEARCH_USER_PATHS' => 'YES',
|
'OTHER_CFLAGS' => '-fmodules -fcxx-modules'
|
||||||
'USER_HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/mimetic_filament/ios/include"',
|
}
|
||||||
'OTHER_CFLAGS' => '-fmodules -fcxx-modules' }
|
|
||||||
s.swift_version = '5.0'
|
s.swift_version = '5.0'
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include <filament/Camera.h>
|
#include <filament/Camera.h>
|
||||||
#include <filament/ColorGrading.h>
|
#include <filament/ColorGrading.h>
|
||||||
#include <filament/Engine.h>
|
#include <filament/Engine.h>
|
||||||
|
|
||||||
#include <filament/IndexBuffer.h>
|
#include <filament/IndexBuffer.h>
|
||||||
#include <filament/RenderableManager.h>
|
#include <filament/RenderableManager.h>
|
||||||
#include <filament/Renderer.h>
|
#include <filament/Renderer.h>
|
||||||
@@ -28,6 +29,7 @@
|
|||||||
#include <filament/TransformManager.h>
|
#include <filament/TransformManager.h>
|
||||||
#include <filament/VertexBuffer.h>
|
#include <filament/VertexBuffer.h>
|
||||||
#include <filament/View.h>
|
#include <filament/View.h>
|
||||||
|
#include <filament/Viewport.h>
|
||||||
|
|
||||||
#include <filament/IndirectLight.h>
|
#include <filament/IndirectLight.h>
|
||||||
#include <filament/LightManager.h>
|
#include <filament/LightManager.h>
|
||||||
@@ -39,6 +41,7 @@
|
|||||||
#include <camutils/Manipulator.h>
|
#include <camutils/Manipulator.h>
|
||||||
|
|
||||||
#include <utils/NameComponentManager.h>
|
#include <utils/NameComponentManager.h>
|
||||||
|
#include <utils/JobSystem.h>
|
||||||
|
|
||||||
#include <math/vec3.h>
|
#include <math/vec3.h>
|
||||||
#include <math/vec4.h>
|
#include <math/vec4.h>
|
||||||
@@ -47,6 +50,13 @@
|
|||||||
|
|
||||||
#include <image/KtxUtility.h>
|
#include <image/KtxUtility.h>
|
||||||
|
|
||||||
|
#include <gltfio/Animator.h>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
using namespace filament;
|
using namespace filament;
|
||||||
using namespace filament::math;
|
using namespace filament::math;
|
||||||
using namespace gltfio;
|
using namespace gltfio;
|
||||||
@@ -97,7 +107,7 @@ FilamentViewer::FilamentViewer(
|
|||||||
_resourceLoader = new ResourceLoader(
|
_resourceLoader = new ResourceLoader(
|
||||||
{.engine = _engine, .normalizeSkinningWeights = true, .recomputeBoundingBoxes = false});
|
{.engine = _engine, .normalizeSkinningWeights = true, .recomputeBoundingBoxes = false});
|
||||||
|
|
||||||
_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);
|
//Manipulator<float>::Builder().orbitHomePosition(0.0f, 0.0f, 0.0f).targetPosition(0.0f, 0.0f, 0).build(Mode::ORBIT);
|
||||||
_asset = nullptr;
|
_asset = nullptr;
|
||||||
@@ -107,15 +117,15 @@ FilamentViewer::~FilamentViewer() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FilamentViewer::loadResources() {
|
void FilamentViewer::loadResources(string relativeResourcePath) {
|
||||||
const char* const* const resourceUris = _asset->getResourceUris();
|
const char* const* const resourceUris = _asset->getResourceUris();
|
||||||
const size_t resourceUriCount = _asset->getResourceUriCount();
|
const size_t resourceUriCount = _asset->getResourceUriCount();
|
||||||
for (size_t i = 0; i < resourceUriCount; i++) {
|
for (size_t i = 0; i < resourceUriCount; i++) {
|
||||||
const char* const uri = resourceUris[i];
|
string uri = relativeResourcePath + string(resourceUris[i]);
|
||||||
ResourceBuffer buf = _loadResource(uri);
|
ResourceBuffer buf = _loadResource(uri.c_str());
|
||||||
ResourceLoader::BufferDescriptor b(
|
ResourceLoader::BufferDescriptor b(
|
||||||
buf.data, buf.size, (ResourceLoader::BufferDescriptor::Callback)&_freeResource, nullptr);
|
buf.data, buf.size, (ResourceLoader::BufferDescriptor::Callback)&_freeResource, nullptr);
|
||||||
_resourceLoader->addResourceData(uri, std::move(b));
|
_resourceLoader->addResourceData(resourceUris[i], std::move(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
_resourceLoader->loadResources(_asset);
|
_resourceLoader->loadResources(_asset);
|
||||||
@@ -133,7 +143,7 @@ void FilamentViewer::loadResources() {
|
|||||||
_scene->addEntities(_asset->getEntities(), _asset->getEntityCount());
|
_scene->addEntities(_asset->getEntities(), _asset->getEntityCount());
|
||||||
};
|
};
|
||||||
|
|
||||||
void FilamentViewer::loadGltf(const char* const uri) {
|
void FilamentViewer::loadGltf(const char* const uri, const char* const relativeResourcePath) {
|
||||||
_resourceLoader->asyncCancelLoad();
|
_resourceLoader->asyncCancelLoad();
|
||||||
_resourceLoader->evictResourceData();
|
_resourceLoader->evictResourceData();
|
||||||
if(_asset) {
|
if(_asset) {
|
||||||
@@ -150,7 +160,13 @@ void FilamentViewer::loadGltf(const char* const uri) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadResources();
|
loadResources(string(relativeResourcePath) + string("/"));
|
||||||
|
|
||||||
|
_freeResource((void*)rbuf.data, rbuf.size, nullptr);
|
||||||
|
|
||||||
|
transformToUnitCube();
|
||||||
|
|
||||||
|
startTime = std::chrono::high_resolution_clock::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -163,6 +179,7 @@ void FilamentViewer::loadSkybox(const char* const skyboxPath, const char* const
|
|||||||
_skyboxTexture = image::ktx::createTexture(_engine, skyboxBundle, false);
|
_skyboxTexture = image::ktx::createTexture(_engine, skyboxBundle, false);
|
||||||
_skybox = filament::Skybox::Builder().environment(_skyboxTexture).build(*_engine);
|
_skybox = filament::Skybox::Builder().environment(_skyboxTexture).build(*_engine);
|
||||||
_scene->setSkybox(_skybox);
|
_scene->setSkybox(_skybox);
|
||||||
|
_freeResource((void*)skyboxBuffer.data, skyboxBuffer.size, nullptr);
|
||||||
|
|
||||||
// Load IBL.
|
// Load IBL.
|
||||||
ResourceBuffer iblBuffer = _loadResource(iblPath);
|
ResourceBuffer iblBuffer = _loadResource(iblPath);
|
||||||
@@ -179,6 +196,8 @@ void FilamentViewer::loadSkybox(const char* const skyboxPath, const char* const
|
|||||||
.build(*_engine);
|
.build(*_engine);
|
||||||
_scene->setIndirectLight(_indirectLight);
|
_scene->setIndirectLight(_indirectLight);
|
||||||
|
|
||||||
|
_freeResource((void*)iblBuffer.data, iblBuffer.size, nullptr);
|
||||||
|
|
||||||
// Always add a direct light source since it is required for shadowing.
|
// Always add a direct light source since it is required for shadowing.
|
||||||
_sun = EntityManager::get().create();
|
_sun = EntityManager::get().create();
|
||||||
LightManager::Builder(LightManager::Type::DIRECTIONAL)
|
LightManager::Builder(LightManager::Type::DIRECTIONAL)
|
||||||
@@ -190,6 +209,20 @@ void FilamentViewer::loadSkybox(const char* const skyboxPath, const char* const
|
|||||||
_scene->addEntity(_sun);
|
_scene->addEntity(_sun);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FilamentViewer::transformToUnitCube() {
|
||||||
|
if (!_asset) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto& tm = _engine->getTransformManager();
|
||||||
|
auto aabb = _asset->getBoundingBox();
|
||||||
|
auto center = aabb.center();
|
||||||
|
auto halfExtent = aabb.extent();
|
||||||
|
auto maxExtent = max(halfExtent) * 2;
|
||||||
|
auto scaleFactor = 2.0f / maxExtent;
|
||||||
|
auto transform = math::mat4f::scaling(scaleFactor) * math::mat4f::translation(-center);
|
||||||
|
tm.setTransform(tm.getInstance(_asset->getRoot()), transform);
|
||||||
|
}
|
||||||
|
|
||||||
void FilamentViewer::cleanup() {
|
void FilamentViewer::cleanup() {
|
||||||
_resourceLoader->asyncCancelLoad();
|
_resourceLoader->asyncCancelLoad();
|
||||||
_assetLoader->destroyAsset(_asset);
|
_assetLoader->destroyAsset(_asset);
|
||||||
@@ -197,5 +230,47 @@ void FilamentViewer::cleanup() {
|
|||||||
AssetLoader::destroy(&_assetLoader);
|
AssetLoader::destroy(&_assetLoader);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void FilamentViewer::render() {
|
||||||
|
if (!_view || !_mainCamera || !manipulator) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Extract the camera basis from the helper and push it to the Filament camera.
|
||||||
|
math::float3 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);
|
||||||
|
|
||||||
|
if(_animator) {
|
||||||
|
// typedef std::chrono::high_resolution_clock clock;
|
||||||
|
typedef std::chrono::duration<float, std::milli> duration;
|
||||||
|
duration dur = std::chrono::high_resolution_clock::now() - startTime;
|
||||||
|
if (_animator->getAnimationCount() > 0) {
|
||||||
|
_animator->applyAnimation(0, dur.count() / 1000);
|
||||||
|
}
|
||||||
|
_animator->updateBoneMatrices();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render the scene, unless the renderer wants to skip the frame.
|
||||||
|
if (_renderer->beginFrame(_swapChain)) {
|
||||||
|
_renderer->render(_view);
|
||||||
|
_renderer->endFrame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilamentViewer::updateViewportAndCameraProjection(int width, int height, float contentScaleFactor) {
|
||||||
|
if (!_view || !_mainCamera || !manipulator) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
manipulator->setViewport(width, height);
|
||||||
|
|
||||||
|
const uint32_t _width = width * contentScaleFactor;
|
||||||
|
const uint32_t _height = height * contentScaleFactor;
|
||||||
|
_view->setViewport({0, 0, _width, _height});
|
||||||
|
|
||||||
|
const double aspect = (double)width / height;
|
||||||
|
_mainCamera->setLensProjection(_cameraFocalLength, aspect, kNearPlane, kFarPlane);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
#include <filament/Camera.h>
|
#include <filament/Camera.h>
|
||||||
#include <filament/ColorGrading.h>
|
#include <filament/ColorGrading.h>
|
||||||
#include <filament/Engine.h>
|
#include <filament/Engine.h>
|
||||||
@@ -26,6 +28,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace filament;
|
using namespace filament;
|
||||||
@@ -40,7 +43,7 @@ namespace mimetic {
|
|||||||
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;
|
||||||
const uint32_t size;
|
const uint64_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
using LoadResource = std::function<ResourceBuffer(const char* uri)>;
|
using LoadResource = std::function<ResourceBuffer(const char* uri)>;
|
||||||
@@ -50,15 +53,22 @@ namespace mimetic {
|
|||||||
public:
|
public:
|
||||||
FilamentViewer(void* layer, LoadResource loadResource, FreeResource freeResource);
|
FilamentViewer(void* layer, LoadResource loadResource, FreeResource freeResource);
|
||||||
~FilamentViewer();
|
~FilamentViewer();
|
||||||
void loadGltf(const char* const uri);
|
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 render();
|
||||||
|
Manipulator<float>* manipulator;
|
||||||
private:
|
private:
|
||||||
void loadResources();
|
void loadResources(std::string relativeResourcePath);
|
||||||
|
void transformToUnitCube();
|
||||||
void cleanup();
|
void cleanup();
|
||||||
void* _layer;
|
void* _layer;
|
||||||
|
|
||||||
LoadResource _loadResource;
|
LoadResource _loadResource;
|
||||||
FreeResource _freeResource;
|
FreeResource _freeResource;
|
||||||
|
|
||||||
|
std::chrono::high_resolution_clock::time_point startTime;
|
||||||
|
|
||||||
Scene* _scene;
|
Scene* _scene;
|
||||||
View* _view;
|
View* _view;
|
||||||
Engine* _engine;
|
Engine* _engine;
|
||||||
@@ -69,8 +79,6 @@ namespace mimetic {
|
|||||||
|
|
||||||
Animator* _animator;
|
Animator* _animator;
|
||||||
|
|
||||||
Manipulator<float>* _manipulator;
|
|
||||||
|
|
||||||
AssetLoader* _assetLoader;
|
AssetLoader* _assetLoader;
|
||||||
FilamentAsset* _asset = nullptr;
|
FilamentAsset* _asset = nullptr;
|
||||||
NameComponentManager* _ncm;
|
NameComponentManager* _ncm;
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ abstract class FilamentController {
|
|||||||
Future initialize();
|
Future initialize();
|
||||||
Future loadSkybox(String skyboxPath, String lightingPath);
|
Future loadSkybox(String skyboxPath, String lightingPath);
|
||||||
Future loadGlb(String path);
|
Future loadGlb(String path);
|
||||||
|
Future loadGltf(String path, String relativeResourcePath);
|
||||||
|
Future panStart(double x, double y);
|
||||||
|
Future panUpdate(double x, double y);
|
||||||
|
Future panEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
class MimeticFilamentController extends FilamentController {
|
class MimeticFilamentController extends FilamentController {
|
||||||
@@ -23,11 +27,27 @@ class MimeticFilamentController extends FilamentController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future loadSkybox(String path) {
|
Future loadSkybox(String skyboxPath, String lightingPath) async {
|
||||||
throw Exception();
|
await _channel.invokeMethod("loadSkybox", [skyboxPath, lightingPath]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future loadGlb(String path) {
|
Future loadGlb(String path) {
|
||||||
throw Exception();
|
throw Exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future loadGltf(String path, String relativeResourcePath) async {
|
||||||
|
await _channel.invokeMethod("loadGltf", [path, relativeResourcePath]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future panStart(double x, double y) async {
|
||||||
|
await _channel.invokeMethod("panStart", [x.toInt(), y.toInt()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future panUpdate(double x, double y) async {
|
||||||
|
await _channel.invokeMethod("panUpdate", [x.toInt(), y.toInt()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future panEnd() async {
|
||||||
|
await _channel.invokeMethod("panEnd");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ environment:
|
|||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
ffi:
|
||||||
|
|
||||||
plugin_platform_interface: ^2.0.0
|
plugin_platform_interface: ^2.0.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|||||||
Reference in New Issue
Block a user