upgrade to Filament 1.21.0
This commit is contained in:
@@ -3,21 +3,18 @@
|
||||
#endif /* FilamentNativeViewFactory_h */
|
||||
|
||||
#import <Flutter/Flutter.h>
|
||||
#import "FilamentViewController.h"
|
||||
|
||||
#include "FilamentViewer.hpp"
|
||||
|
||||
using namespace polyvox;
|
||||
|
||||
static const id VIEW_TYPE = @"app.polyvox.filament/filament_view";
|
||||
|
||||
@interface FilamentMethodCallHandler : FlutterMethodChannel
|
||||
- (void)handleMethodCall:(FlutterMethodCall* _Nonnull)call result:( FlutterResult _Nonnull)result;
|
||||
- (polyvox::FilamentViewer*) _viewer;
|
||||
- (polyvox::ResourceBuffer)loadResource:(const char* const)path;
|
||||
- (void)freeResource:(void*)mem size:(size_t)size misc:(void*)misc;
|
||||
- (void)freeResource:(polyvox::ResourceBuffer)rb;
|
||||
- (void)ready;
|
||||
- (instancetype)initWithController:(FilamentViewController*)controller
|
||||
registrar:(NSObject<FlutterPluginRegistrar>*)registrar
|
||||
viewId:(int64_t)viewId
|
||||
layer:(void*)layer;
|
||||
|
||||
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar viewId:(int64_t)viewId viewer:(FilamentViewer*)viewer;
|
||||
@end
|
||||
|
||||
@@ -1,34 +1,24 @@
|
||||
#import "FilamentMethodCallHandler.h"
|
||||
#import "FilamentViewController.h"
|
||||
#import "FilamentNativeViewFactory.h"
|
||||
|
||||
static const FilamentMethodCallHandler* _handler;
|
||||
static int _resourceId = 0;
|
||||
|
||||
static polyvox::ResourceBuffer loadResourceGlobal(const char* name) {
|
||||
return [_handler loadResource:name];
|
||||
}
|
||||
|
||||
static void* freeResourceGlobal(ResourceBuffer rb) {
|
||||
[_handler freeResource:rb ];
|
||||
return nullptr;
|
||||
}
|
||||
using namespace polyvox;
|
||||
|
||||
@implementation FilamentMethodCallHandler {
|
||||
FilamentViewController *_controller;
|
||||
FlutterMethodChannel* _channel;
|
||||
polyvox::FilamentViewer* _viewer;
|
||||
void* _layer;
|
||||
FilamentViewer* _viewer;
|
||||
|
||||
NSObject<FlutterPluginRegistrar>* _registrar;
|
||||
}
|
||||
- (instancetype)initWithController:(FilamentViewController*)controller
|
||||
registrar:(NSObject<FlutterPluginRegistrar>*)registrar
|
||||
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar
|
||||
viewId:(int64_t)viewId
|
||||
layer:(void*)layer
|
||||
viewer:(FilamentViewer*)viewer
|
||||
|
||||
{
|
||||
_layer = layer;
|
||||
_registrar = registrar;
|
||||
_controller = controller;
|
||||
_viewer = viewer;
|
||||
|
||||
NSString* channelName = [NSString stringWithFormat:@"%@_%d",VIEW_TYPE,viewId];
|
||||
_channel = [FlutterMethodChannel
|
||||
methodChannelWithName:channelName
|
||||
@@ -36,65 +26,45 @@ static void* freeResourceGlobal(ResourceBuffer rb) {
|
||||
[_channel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
|
||||
[self handleMethodCall:call result:result];
|
||||
}];
|
||||
_handler = self;
|
||||
|
||||
_viewer = new polyvox::FilamentViewer(_layer, nullptr, nullptr, loadResourceGlobal, freeResourceGlobal);
|
||||
[_controller setViewer:_viewer];
|
||||
[_controller startDisplayLink];
|
||||
|
||||
[self ready];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)handleMethodCall:(FlutterMethodCall* _Nonnull)call result:(FlutterResult _Nonnull )result {
|
||||
if(!_viewer) {
|
||||
result([FlutterError errorWithCode:@"UNAVAILABLE"
|
||||
message:@"View unavailable"
|
||||
details:nil]);
|
||||
return;
|
||||
}
|
||||
if([@"loadSkybox" isEqualToString:call.method]) {
|
||||
if(!_viewer)
|
||||
return;
|
||||
|
||||
_viewer->loadSkybox([call.arguments[0] UTF8String], [call.arguments[1] UTF8String]);
|
||||
result(@"OK");
|
||||
} else if([@"loadGlb" isEqualToString:call.method]) {
|
||||
if(!_viewer)
|
||||
return; // TODO should throw exception here
|
||||
_viewer->loadGlb([call.arguments UTF8String]);
|
||||
result(@"OK");
|
||||
} else if([@"loadGltf" isEqualToString:call.method]) {
|
||||
if(!_viewer)
|
||||
return; // TODO should throw exception here
|
||||
_viewer->loadGltf([call.arguments[0] UTF8String], [call.arguments[1] UTF8String]);
|
||||
result(@"OK");
|
||||
} else if([@"setCamera" isEqualToString:call.method]) {
|
||||
if(!_viewer)
|
||||
return; // TODO should throw exception here
|
||||
_viewer->setCamera([call.arguments UTF8String]);
|
||||
result(@"OK");
|
||||
} else if([@"panStart" isEqualToString:call.method]) {
|
||||
if(!_viewer)
|
||||
return;
|
||||
_viewer->manipulator->grabBegin([call.arguments[0] intValue], [call.arguments[1] intValue], true);
|
||||
result(@"OK");
|
||||
} else if([@"panUpdate" isEqualToString:call.method]) {
|
||||
if(!_viewer)
|
||||
return;
|
||||
_viewer->manipulator->grabUpdate([call.arguments[0] intValue], [call.arguments[1] intValue]);
|
||||
result(@"OK");
|
||||
} else if([@"panEnd" isEqualToString:call.method]) {
|
||||
if(!_viewer)
|
||||
return;
|
||||
_viewer->manipulator->grabEnd();
|
||||
result(@"OK");
|
||||
} else if([@"rotateStart" isEqualToString:call.method]) {
|
||||
if(!_viewer)
|
||||
return;
|
||||
_viewer->manipulator->grabBegin([call.arguments[0] intValue], [call.arguments[1] intValue], false);
|
||||
result(@"OK");
|
||||
} else if([@"rotateUpdate" isEqualToString:call.method]) {
|
||||
if(!_viewer)
|
||||
return;
|
||||
_viewer->manipulator->grabUpdate([call.arguments[0] intValue], [call.arguments[1] intValue]);
|
||||
result(@"OK");
|
||||
} else if([@"rotateEnd" isEqualToString:call.method]) {
|
||||
if(!_viewer)
|
||||
return;
|
||||
_viewer->manipulator->grabEnd();
|
||||
result(@"OK");
|
||||
} else if([@"releaseSourceAssets" isEqualToString:call.method]) {
|
||||
@@ -104,36 +74,29 @@ static void* freeResourceGlobal(ResourceBuffer rb) {
|
||||
NSArray* frameData = call.arguments[0];
|
||||
NSNumber* numWeights = call.arguments[1];
|
||||
NSNumber* frameRate = call.arguments[2];
|
||||
NSUInteger numElements = [frameData count];
|
||||
|
||||
float* framesArr = (float*)malloc([frameData count] *sizeof(float));
|
||||
for(int i =0 ; i < [frameData count]; i++) {
|
||||
*(framesArr+i) = [[frameData objectAtIndex:i] floatValue];
|
||||
}
|
||||
_viewer->animateWeights((float*)framesArr, [numWeights intValue], [frameData count] / numWeights, [frameRate floatValue]);
|
||||
result(@"OK");
|
||||
} else if([@"createMorpher" isEqualToString:call.method]) {
|
||||
const char* meshName = [call.arguments[0] UTF8String];
|
||||
NSArray* primitiveIndices = call.arguments[1];
|
||||
int* primitiveIndicesArr = (int*)malloc([primitiveIndices count] *sizeof(int));
|
||||
for(int i =0 ; i < [primitiveIndices count]; i++) {
|
||||
primitiveIndicesArr[i] = [[primitiveIndices objectAtIndex:i] intValue];
|
||||
}
|
||||
_viewer->createMorpher(meshName, primitiveIndicesArr, [primitiveIndices count]);
|
||||
free(primitiveIndicesArr);
|
||||
NSUInteger numFrames = numElements / [ numWeights intValue ];
|
||||
_viewer->animateWeights((float*)framesArr, [numWeights intValue], numFrames, [frameRate floatValue]);
|
||||
result(@"OK");
|
||||
} else if([@"playAnimation" isEqualToString:call.method]) {
|
||||
_viewer->playAnimation([call.arguments intValue]);
|
||||
int animationIndex = [call.arguments[0] intValue];
|
||||
bool loop = call.arguments[1];
|
||||
_viewer->playAnimation(animationIndex, loop);
|
||||
result(@"OK");
|
||||
} else if([@"getTargetNames" isEqualToString:call.method]) {
|
||||
polyvox::StringList list = _viewer->getTargetNames([call.arguments UTF8String]);
|
||||
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]) {
|
||||
if(!_viewer)
|
||||
return;
|
||||
|
||||
NSArray* nWeights = call.arguments;
|
||||
|
||||
int count = [nWeights count];
|
||||
@@ -144,17 +107,14 @@ static void* freeResourceGlobal(ResourceBuffer rb) {
|
||||
_viewer->applyWeights(weights, count);
|
||||
result(@"OK");
|
||||
} else if([@"zoom" isEqualToString:call.method]) {
|
||||
if(!_viewer)
|
||||
return;
|
||||
_viewer->manipulator->scroll(0.0f, 0.0f, [call.arguments floatValue]);
|
||||
result(@"OK");
|
||||
} else {
|
||||
|
||||
result(FlutterMethodNotImplemented);
|
||||
}
|
||||
}
|
||||
|
||||
- (polyvox::ResourceBuffer)loadResource:(const char* const)path {
|
||||
- (ResourceBuffer)loadResource:(const char* const)path {
|
||||
NSString* p = [NSString stringWithFormat:@"%s", path];
|
||||
NSString* key = [_registrar lookupKeyForAsset:p];
|
||||
NSString* nsPath = [[NSBundle mainBundle] pathForResource:key
|
||||
@@ -167,12 +127,13 @@ static void* freeResourceGlobal(ResourceBuffer rb) {
|
||||
NSData* buffer = [NSData dataWithContentsOfFile:nsPath];
|
||||
void* cpy = malloc([buffer length]);
|
||||
memcpy(cpy, [buffer bytes], [buffer length]); // can we avoid this copy somehow?
|
||||
polyvox::ResourceBuffer rbuf(cpy, [buffer length]);
|
||||
_resourceId++;
|
||||
ResourceBuffer rbuf(cpy, [buffer length], _resourceId);
|
||||
return rbuf;
|
||||
}
|
||||
|
||||
- (void)freeResource:(ResourceBuffer)rb {
|
||||
free(rb.data);
|
||||
free((void*)rb.data);
|
||||
}
|
||||
|
||||
- (void)ready {
|
||||
|
||||
@@ -1,7 +1,19 @@
|
||||
#import "FilamentNativeViewFactory.h"
|
||||
#import "FilamentViewController.h"
|
||||
#import "FilamentMethodCallHandler.h"
|
||||
|
||||
using namespace polyvox;
|
||||
|
||||
static const FilamentMethodCallHandler* _shandler;
|
||||
|
||||
static ResourceBuffer loadResource(const char* name) {
|
||||
return [_shandler loadResource:name];
|
||||
}
|
||||
|
||||
static void* freeResource(ResourceBuffer rb) {
|
||||
[_shandler freeResource:rb ];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@implementation FilamentNativeViewFactory {
|
||||
NSObject<FlutterPluginRegistrar>* _registrar;
|
||||
}
|
||||
@@ -25,28 +37,24 @@
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@implementation FilamentNativeView {
|
||||
FilamentView* _view;
|
||||
FilamentViewController* _controller;
|
||||
polyvox::FilamentViewer* _viewer;
|
||||
FilamentViewer* _viewer;
|
||||
FilamentMethodCallHandler* _handler;
|
||||
void* _layer;
|
||||
}
|
||||
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
viewIdentifier:(int64_t)viewId
|
||||
arguments:(id _Nullable)args
|
||||
registrar:(NSObject<FlutterPluginRegistrar>*)registrar {
|
||||
if (self = [super init]) {
|
||||
_view = [[FilamentView alloc] init];
|
||||
_controller = [[FilamentViewController alloc] initWithRegistrar:registrar view:_view];
|
||||
[_controller viewDidLoad];
|
||||
_layer = (__bridge_retained void*)[_view layer];
|
||||
_handler = [[FilamentMethodCallHandler alloc] initWithController:_controller registrar:registrar viewId:viewId layer:_layer];
|
||||
[_handler ready];
|
||||
_viewer = new FilamentViewer(_layer, loadResource, freeResource);
|
||||
[_view setViewer:_viewer];
|
||||
_handler = [[FilamentMethodCallHandler alloc] initWithRegistrar:registrar viewId:viewId viewer:_viewer ];
|
||||
_shandler = _handler;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
@interface FilamentView : UIView
|
||||
- (void)setViewer:(polyvox::FilamentViewer*)viewer;
|
||||
- (void)startDisplayLink;
|
||||
- (void)stopDisplayLink;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@@ -20,22 +20,22 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace polyvox;
|
||||
|
||||
@interface FilamentView ()
|
||||
- (void)initCommon;
|
||||
- (void)setViewer:(polyvox::FilamentViewer*)viewer;
|
||||
- (void)setViewer:(FilamentViewer*)viewer;
|
||||
@end
|
||||
|
||||
@implementation FilamentView {
|
||||
polyvox::FilamentViewer* _viewer;
|
||||
FilamentViewer* _viewer;
|
||||
CADisplayLink* _displayLink;
|
||||
}
|
||||
|
||||
- (void)setViewer:(polyvox::FilamentViewer*)viewer {
|
||||
- (void)setViewer:(FilamentViewer*)viewer {
|
||||
_viewer = viewer;
|
||||
_viewer->updateViewportAndCameraProjection(self.bounds.size.width, self.bounds.size.height, self.contentScaleFactor);
|
||||
}
|
||||
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
if (self = [super initWithFrame:frame]) {
|
||||
[self initCommon];
|
||||
@@ -65,9 +65,12 @@ using namespace std;
|
||||
|
||||
- (void)layoutSubviews {
|
||||
[super layoutSubviews];
|
||||
NSLog(@"layout subview");
|
||||
|
||||
if(_viewer) {
|
||||
_viewer->updateViewportAndCameraProjection(self.bounds.size.width, self.bounds.size.height, self.contentScaleFactor);
|
||||
}
|
||||
[self startDisplayLink];
|
||||
}
|
||||
|
||||
- (void)setContentScaleFactor:(CGFloat)contentScaleFactor {
|
||||
@@ -77,4 +80,29 @@ using namespace std;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)rect {
|
||||
NSLog(@"Drawing rect");
|
||||
[super drawRect:rect];
|
||||
}
|
||||
|
||||
- (void)startDisplayLink {
|
||||
NSLog(@"Starting display link");
|
||||
|
||||
[self stopDisplayLink];
|
||||
|
||||
// Call our render method 60 times a second.
|
||||
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(render)];
|
||||
_displayLink.preferredFramesPerSecond = 60;
|
||||
[_displayLink addToRunLoop:NSRunLoop.currentRunLoop forMode:NSDefaultRunLoopMode];
|
||||
}
|
||||
|
||||
- (void)stopDisplayLink {
|
||||
[_displayLink invalidate];
|
||||
_displayLink = nil;
|
||||
}
|
||||
|
||||
- (void)render {
|
||||
_viewer->render();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "FilamentView.h"
|
||||
#import "Flutter/Flutter.h"
|
||||
#import "FilamentViewer.hpp"
|
||||
|
||||
@interface FilamentViewController : UIViewController
|
||||
|
||||
@property(weak, nonatomic) IBOutlet FilamentView* modelView;
|
||||
- (void)setViewer:(polyvox::FilamentViewer*)viewer;
|
||||
- (void)startDisplayLink;
|
||||
- (void)stopDisplayLink;
|
||||
|
||||
-initWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar view:(FilamentView*)view;
|
||||
|
||||
@end
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FilamentViewController.h"
|
||||
#import "FilamentView.h"
|
||||
#import "FilamentViewer.hpp"
|
||||
#import <Flutter/Flutter.h>
|
||||
|
||||
@implementation FilamentViewController {
|
||||
CADisplayLink* _displayLink;
|
||||
NSObject<FlutterPluginRegistrar>* _registrar;
|
||||
polyvox::FilamentViewer* _viewer;
|
||||
FilamentView* _view;
|
||||
}
|
||||
|
||||
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar
|
||||
view:(FilamentView*)view {
|
||||
if (self = [super init]) {
|
||||
_registrar = registrar;
|
||||
_view = view;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
- (void)setViewer:(polyvox::FilamentViewer*)viewer {
|
||||
_viewer = viewer;
|
||||
[_view setViewer:_viewer];
|
||||
}
|
||||
#pragma mark UIViewController methods
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated {
|
||||
[self startDisplayLink];
|
||||
}
|
||||
|
||||
- (void)viewWillDisappear:(BOOL)animated {
|
||||
[self stopDisplayLink];
|
||||
}
|
||||
|
||||
- (void)startDisplayLink {
|
||||
[self stopDisplayLink];
|
||||
|
||||
// Call our render method 60 times a second.
|
||||
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(render)];
|
||||
_displayLink.preferredFramesPerSecond = 60;
|
||||
[_displayLink addToRunLoop:NSRunLoop.currentRunLoop forMode:NSDefaultRunLoopMode];
|
||||
}
|
||||
|
||||
- (void)stopDisplayLink {
|
||||
[_displayLink invalidate];
|
||||
_displayLink = nil;
|
||||
}
|
||||
|
||||
- (void)render {
|
||||
if(_viewer) {
|
||||
_viewer->render();
|
||||
}
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,15 +0,0 @@
|
||||
#import "PolyvoxFilamentPlugin.h"
|
||||
#if __has_include(<polyvox_filament/polyvox_filament-Swift.h>)
|
||||
#import <polyvox_filament/polyvox_filament-Swift.h>
|
||||
#else
|
||||
// Support project import fallback if the generated compatibility header
|
||||
// is not copied when this plugin is created as a library.
|
||||
// https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816
|
||||
#import "polyvox_filament-Swift.h"
|
||||
#endif
|
||||
|
||||
@implementation PolyvoxFilamentPlugin
|
||||
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
|
||||
[SwiftPolyvoxFilamentPlugin registerWithRegistrar:registrar];
|
||||
}
|
||||
@end
|
||||
@@ -1,14 +0,0 @@
|
||||
import Flutter
|
||||
import UIKit
|
||||
|
||||
public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin {
|
||||
public static func register(with registrar: FlutterPluginRegistrar) {
|
||||
let channel = FlutterMethodChannel(name: "app.polyvox.filament", binaryMessenger: registrar.messenger())
|
||||
let instance = SwiftPolyvoxFilamentPlugin()
|
||||
registrar.addMethodCallDelegate(instance, channel: channel)
|
||||
}
|
||||
|
||||
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||||
result("iOS " + UIDevice.current.systemVersion)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user