replace view with texture, move plugin to Swift implementation
This commit is contained in:
@@ -1,20 +0,0 @@
|
||||
#ifndef FilamentMethodCallHandler_h
|
||||
#define FilamentMethodCallHandler_h
|
||||
#endif /* FilamentNativeViewFactory_h */
|
||||
|
||||
#import <Flutter/Flutter.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:(polyvox::ResourceBuffer)rb;
|
||||
- (void)ready;
|
||||
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar viewId:(int64_t)viewId viewer:(FilamentViewer*)viewer;
|
||||
@end
|
||||
@@ -1,170 +0,0 @@
|
||||
#import "FilamentMethodCallHandler.h"
|
||||
#import "FilamentNativeViewFactory.h"
|
||||
|
||||
static int _resourceId = 0;
|
||||
|
||||
using namespace polyvox;
|
||||
using namespace std;
|
||||
|
||||
@implementation FilamentMethodCallHandler {
|
||||
FlutterMethodChannel* _channel;
|
||||
FilamentViewer* _viewer;
|
||||
|
||||
NSObject<FlutterPluginRegistrar>* _registrar;
|
||||
}
|
||||
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar
|
||||
viewId:(int64_t)viewId
|
||||
viewer:(FilamentViewer*)viewer
|
||||
|
||||
{
|
||||
_registrar = registrar;
|
||||
_viewer = viewer;
|
||||
|
||||
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];
|
||||
}];
|
||||
[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]) {
|
||||
_viewer->loadSkybox([call.arguments UTF8String]);
|
||||
result(@"OK");
|
||||
} else if([@"removeSkybox" isEqualToString:call.method]) {
|
||||
_viewer->removeSkybox();
|
||||
result(@"OK");
|
||||
} else if([@"loadIbl" isEqualToString:call.method]) {
|
||||
_viewer->loadIbl([call.arguments UTF8String]);
|
||||
result(@"OK");
|
||||
} else if([@"removeIbl" isEqualToString:call.method]) {
|
||||
_viewer->removeIbl();
|
||||
result(@"OK");
|
||||
} else if([@"loadGlb" isEqualToString:call.method]) {
|
||||
_viewer->loadGlb([call.arguments UTF8String]);
|
||||
result(@"OK");
|
||||
} else if([@"loadGltf" isEqualToString:call.method]) {
|
||||
_viewer->loadGltf([call.arguments[0] UTF8String], [call.arguments[1] UTF8String]);
|
||||
result(@"OK");
|
||||
} else if([@"setCamera" isEqualToString:call.method]) {
|
||||
_viewer->setCamera([call.arguments UTF8String]);
|
||||
result(@"OK");
|
||||
} else if([@"panStart" isEqualToString:call.method]) {
|
||||
_viewer->manipulator->grabBegin([call.arguments[0] intValue], [call.arguments[1] intValue], true);
|
||||
result(@"OK");
|
||||
} else if([@"panUpdate" isEqualToString:call.method]) {
|
||||
_viewer->manipulator->grabUpdate([call.arguments[0] intValue], [call.arguments[1] intValue]);
|
||||
result(@"OK");
|
||||
} else if([@"panEnd" isEqualToString:call.method]) {
|
||||
_viewer->manipulator->grabEnd();
|
||||
result(@"OK");
|
||||
} else if([@"rotateStart" isEqualToString:call.method]) {
|
||||
_viewer->manipulator->grabBegin([call.arguments[0] intValue], [call.arguments[1] intValue], false);
|
||||
result(@"OK");
|
||||
} else if([@"rotateUpdate" isEqualToString:call.method]) {
|
||||
_viewer->manipulator->grabUpdate([call.arguments[0] intValue], [call.arguments[1] intValue]);
|
||||
result(@"OK");
|
||||
} else if([@"rotateEnd" isEqualToString:call.method]) {
|
||||
_viewer->manipulator->grabEnd();
|
||||
result(@"OK");
|
||||
} else if([@"animateWeights" isEqualToString:call.method]) {
|
||||
NSArray* frameData = call.arguments[0];
|
||||
NSNumber* numWeights = call.arguments[1];
|
||||
NSNumber* numFrames = call.arguments[2];
|
||||
NSNumber* frameLenInMs = call.arguments[3];
|
||||
|
||||
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], [numFrames intValue], [frameLenInMs floatValue]);
|
||||
result(@"OK");
|
||||
} else if([@"playAnimation" isEqualToString:call.method]) {
|
||||
int animationIndex = [call.arguments[0] intValue];
|
||||
bool loop = call.arguments[1];
|
||||
_viewer->playAnimation(animationIndex, loop);
|
||||
result(@"OK");
|
||||
} else if ([@"stopAnimation" isEqualToString:call.method]) {
|
||||
_viewer->stopAnimation();
|
||||
result(@"OK");
|
||||
} else if([@"getTargetNames" isEqualToString:call.method]) {
|
||||
NSMutableArray* names = [self getTargetNames:call.arguments];
|
||||
result(names);
|
||||
} else if([@"getAnimationNames" isEqualToString:call.method]) {
|
||||
NSMutableArray* names = [self getAnimationNames];
|
||||
result(names);
|
||||
} else if([@"applyWeights" isEqualToString:call.method]) {
|
||||
|
||||
NSArray* nWeights = call.arguments;
|
||||
|
||||
int count = [nWeights count];
|
||||
float weights[count];
|
||||
for(int i=0; i < count; i++) {
|
||||
weights[i] = [nWeights[i] floatValue];
|
||||
}
|
||||
_viewer->applyWeights(weights, count);
|
||||
result(@"OK");
|
||||
} else if([@"zoom" isEqualToString:call.method]) {
|
||||
_viewer->manipulator->scroll(0.0f, 0.0f, [call.arguments floatValue]);
|
||||
result(@"OK");
|
||||
} else {
|
||||
result(FlutterMethodNotImplemented);
|
||||
}
|
||||
}
|
||||
|
||||
- (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 %@", p);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
NSData* buffer = [NSData dataWithContentsOfFile:nsPath];
|
||||
void* cpy = malloc([buffer length]);
|
||||
memcpy(cpy, [buffer bytes], [buffer length]); // can we avoid this copy somehow?
|
||||
_resourceId++;
|
||||
ResourceBuffer rbuf(cpy, [buffer length], _resourceId);
|
||||
return rbuf;
|
||||
}
|
||||
|
||||
- (void)freeResource:(ResourceBuffer)rb {
|
||||
free((void*)rb.data);
|
||||
}
|
||||
|
||||
- (void)ready {
|
||||
[_channel invokeMethod:@"ready" arguments:nil];
|
||||
}
|
||||
|
||||
- (NSMutableArray*) getAnimationNames {
|
||||
unique_ptr<vector<string>> list = _viewer->getAnimationNames();
|
||||
NSMutableArray* asArray = [NSMutableArray arrayWithCapacity:list->size()];
|
||||
for(int i = 0; i < list->size(); i++) {
|
||||
asArray[i] = [NSString stringWithFormat:@"%s", list->at(i).c_str()];
|
||||
}
|
||||
return asArray;
|
||||
}
|
||||
|
||||
- (NSMutableArray*) getTargetNames:(NSString*) meshName {
|
||||
unique_ptr<vector<string>> list = _viewer->getTargetNames([meshName UTF8String]);
|
||||
NSMutableArray* asArray = [NSMutableArray arrayWithCapacity:list->size()];
|
||||
for(int i = 0; i < list->size(); i++) {
|
||||
asArray[i] = [NSString stringWithFormat:@"%s", list->at(i).c_str()];
|
||||
}
|
||||
return asArray;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,25 +0,0 @@
|
||||
#ifndef FilamentNativeViewFactory_h
|
||||
#define FilamentNativeViewFactory_h
|
||||
#endif /* FilamentNativeViewFactory_h */
|
||||
|
||||
#import <Flutter/Flutter.h>
|
||||
#import "FilamentView.h"
|
||||
|
||||
#include "FilamentViewer.hpp"
|
||||
|
||||
|
||||
@interface FilamentNativeViewFactory : NSObject <FlutterPlatformViewFactory>
|
||||
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar;
|
||||
@end
|
||||
|
||||
@interface FilamentNativeView : NSObject <FlutterPlatformView>
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
viewIdentifier:(int64_t)viewId
|
||||
arguments:(id _Nullable)args
|
||||
registrar:(NSObject<FlutterPluginRegistrar>*)registrar;
|
||||
|
||||
- (UIView*)view;
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
#import "FilamentNativeViewFactory.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;
|
||||
}
|
||||
|
||||
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_registrar = registrar;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
|
||||
viewIdentifier:(int64_t)viewId
|
||||
arguments:(id _Nullable)args {
|
||||
return [[FilamentNativeView alloc] initWithFrame:frame
|
||||
viewIdentifier:viewId
|
||||
arguments:args
|
||||
registrar:_registrar];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation FilamentNativeView {
|
||||
FilamentView* _view;
|
||||
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];
|
||||
_layer = (__bridge_retained void*)[_view layer];
|
||||
_viewer = new FilamentViewer(_layer, loadResource, freeResource);
|
||||
[_view setViewer:_viewer];
|
||||
_handler = [[FilamentMethodCallHandler alloc] initWithRegistrar:registrar viewId:viewId viewer:_viewer ];
|
||||
_shandler = _handler;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (UIView*)view {
|
||||
return _view;
|
||||
}
|
||||
|
||||
|
||||
@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>
|
||||
#include "FilamentViewer.hpp"
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* FILModelView is simply a UIView with an OpenGL layer.
|
||||
*
|
||||
*
|
||||
*/
|
||||
@interface FilamentView : UIView
|
||||
- (void)setViewer:(polyvox::FilamentViewer*)viewer;
|
||||
- (void)startDisplayLink;
|
||||
- (void)stopDisplayLink;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,108 +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.
|
||||
*/
|
||||
|
||||
// These defines are set in the "Preprocessor Macros" build setting for each scheme.
|
||||
#include "FilamentView.h"
|
||||
#include "FilamentViewer.hpp"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace polyvox;
|
||||
|
||||
@interface FilamentView ()
|
||||
- (void)initCommon;
|
||||
- (void)setViewer:(FilamentViewer*)viewer;
|
||||
@end
|
||||
|
||||
@implementation FilamentView {
|
||||
FilamentViewer* _viewer;
|
||||
CADisplayLink* _displayLink;
|
||||
}
|
||||
|
||||
- (void)setViewer:(FilamentViewer*)viewer {
|
||||
_viewer = viewer;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
if (self = [super initWithFrame:frame]) {
|
||||
[self initCommon];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder*)coder {
|
||||
if (self = [super initWithCoder:coder]) {
|
||||
[self initCommon];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)initCommon {
|
||||
[self initializeGLLayer];
|
||||
}
|
||||
|
||||
- (void)initializeGLLayer {
|
||||
CAEAGLLayer* glLayer = (CAEAGLLayer*)self.layer;
|
||||
glLayer.opaque = YES;
|
||||
}
|
||||
|
||||
+ (Class)layerClass {
|
||||
return [CAEAGLLayer class];
|
||||
}
|
||||
|
||||
- (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 {
|
||||
[super setContentScaleFactor:contentScaleFactor];
|
||||
if(_viewer) {
|
||||
_viewer->updateViewportAndCameraProjection(self.bounds.size.width, self.bounds.size.height, self.contentScaleFactor);
|
||||
}
|
||||
}
|
||||
|
||||
- (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
|
||||
147
ios/Classes/PolyvoxFilamentApi.cc
Normal file
147
ios/Classes/PolyvoxFilamentApi.cc
Normal file
@@ -0,0 +1,147 @@
|
||||
#ifndef _POLYVOX_FILAMENT_API_H
|
||||
#define _POLYVOX_FILAMENT_API_H
|
||||
|
||||
#include "ResourceBuffer.hpp"
|
||||
#include "FilamentViewer.hpp"
|
||||
|
||||
using namespace polyvox;
|
||||
|
||||
extern "C" {
|
||||
// ResourceBuffer create_resource_buffer(const void* data, const uint32_t size, const uint32_t id) {
|
||||
// return ResourceBuffer {data, size, id };
|
||||
// }
|
||||
|
||||
void* filament_viewer_new(void* texture, ResourceBuffer (*loadResource)(const char*), void (*freeResource)(uint32_t)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void set_background_image(void* viewer, const char* path) {
|
||||
((FilamentViewer*)viewer)->setBackgroundImage(path);
|
||||
}
|
||||
|
||||
void load_skybox(void* viewer, const char* skyboxPath) {
|
||||
((FilamentViewer*)viewer)->loadSkybox(skyboxPath);
|
||||
}
|
||||
|
||||
void load_ibl(void* viewer, const char* iblPath) {
|
||||
((FilamentViewer*)viewer)->loadIbl(iblPath);
|
||||
}
|
||||
|
||||
void remove_skybox(void* viewer) {
|
||||
((FilamentViewer*)viewer)->removeSkybox();
|
||||
}
|
||||
|
||||
|
||||
void remove_ibl(void* viewer) {
|
||||
((FilamentViewer*)viewer)->removeIbl();
|
||||
}
|
||||
|
||||
void* load_glb(void* viewer, const char* assetPath) {
|
||||
return ((FilamentViewer*)viewer)->loadGlb(assetPath);
|
||||
}
|
||||
|
||||
void* load_gltf(void* viewer, const char* assetPath, const char* relativePath) {
|
||||
return ((FilamentViewer*)viewer)->loadGltf(assetPath, relativePath);
|
||||
}
|
||||
|
||||
bool set_camera(void* viewer, void* asset, const char* nodeName) {
|
||||
return ((FilamentViewer*)viewer)->setCamera((SceneAsset*)asset, nodeName);
|
||||
}
|
||||
|
||||
void render(
|
||||
void* viewer
|
||||
) {
|
||||
((FilamentViewer*)viewer)->render();
|
||||
}
|
||||
|
||||
void destroy_swap_chain(void* viewer) {
|
||||
((FilamentViewer*)viewer)->destroySwapChain();
|
||||
}
|
||||
|
||||
void* get_renderer(void* viewer) {
|
||||
return ((FilamentViewer*)viewer)->getRenderer();
|
||||
}
|
||||
|
||||
void update_viewport_and_camera_projection(void* viewer, int width, int height, float scaleFactor) {
|
||||
return ((FilamentViewer*)viewer)->updateViewportAndCameraProjection(width, height, scaleFactor);
|
||||
|
||||
}
|
||||
|
||||
void scroll(void* viewer, float x, float y , float z) {
|
||||
return ((FilamentViewer*)viewer)->manipulator->scroll(x, y, z);
|
||||
}
|
||||
|
||||
void grab_begin(void* viewer, int x, int y, bool pan) {
|
||||
((FilamentViewer*)viewer)->manipulator->grabBegin(x, y, pan);
|
||||
|
||||
}
|
||||
|
||||
void grab_update(void* viewer, int x, int y) {
|
||||
((FilamentViewer*)viewer)->manipulator->grabUpdate(x, y);
|
||||
}
|
||||
|
||||
void grab_end(void* viewer) {
|
||||
((FilamentViewer*)viewer)->manipulator->grabEnd();
|
||||
}
|
||||
|
||||
void apply_weights(void* asset, float* const weights, int count) {
|
||||
((SceneAsset*)asset)->applyWeights(weights, count);
|
||||
}
|
||||
|
||||
void animate_weights(void* asset, float* data, int numWeights, int numFrames, float frameRate) {
|
||||
((SceneAsset*)asset)->animateWeights((float*)data, numWeights, numFrames, frameRate);
|
||||
}
|
||||
|
||||
void play_animation(void* asset, int index, bool loop) {
|
||||
((SceneAsset*)asset)->playAnimation(index, loop);
|
||||
}
|
||||
|
||||
int get_animation_count(void* asset) {
|
||||
auto names = ((SceneAsset*)asset)->getAnimationNames();
|
||||
return names->size();
|
||||
}
|
||||
|
||||
void get_animation_name(void* asset, char* const outPtr, int index) {
|
||||
auto names = ((SceneAsset*)asset)->getAnimationNames();
|
||||
string name = names->at(index);
|
||||
strcpy(outPtr, name.c_str());
|
||||
}
|
||||
|
||||
int get_target_name_count(void* asset, const char* meshName) {
|
||||
unique_ptr<vector<string>> names = ((SceneAsset*)asset)->getTargetNames(meshName);
|
||||
return names->size();
|
||||
}
|
||||
|
||||
void get_target_name(void* asset, const char* meshName, char* const outPtr, int index ) {
|
||||
unique_ptr<vector<string>> names = ((SceneAsset*)asset)->getTargetNames(meshName);
|
||||
string name = names->at(index);
|
||||
strcpy(outPtr, name.c_str());
|
||||
}
|
||||
|
||||
void remove_asset(void* viewer, void* asset) {
|
||||
((FilamentViewer*)viewer)->removeAsset((SceneAsset*)asset);
|
||||
}
|
||||
|
||||
void clear_assets(void* viewer) {
|
||||
((FilamentViewer*)viewer)->clearAssets();
|
||||
}
|
||||
|
||||
void set_texture(void* asset, const char* assetPath, int renderableIndex) {
|
||||
((SceneAsset*)asset)->setTexture(assetPath, renderableIndex);
|
||||
}
|
||||
|
||||
void transform_to_unit_cube(void* asset) {
|
||||
((SceneAsset*)asset)->transformToUnitCube();
|
||||
}
|
||||
|
||||
// void set_position(void* asset, float x, float y, float z) {
|
||||
// ((SceneAsset*)asset)->setPosition(x, y, z);
|
||||
// }
|
||||
|
||||
// void set_rotation(void* asset, float rads, float x, float y, float z) {
|
||||
// ((SceneAsset*)asset)->setRotation(rads, x, y, z);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
56
ios/Classes/PolyvoxFilamentApi.h
Normal file
56
ios/Classes/PolyvoxFilamentApi.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#ifndef _POLYVOX_FILAMENT_API_H
|
||||
#define _POLYVOX_FILAMENT_API_H
|
||||
|
||||
#include "ResourceBuffer.hpp"
|
||||
|
||||
typedef struct ResourceBuffer ResourceBuffer;
|
||||
|
||||
//ResourceBuffer create_resource_buffer(const void* data, const uint32_t size, const uint32_t id);
|
||||
void* filament_viewer_new(void* texture, void* loadResource, void* freeResource);
|
||||
void set_background_image(void* viewer, const char* path);
|
||||
void load_skybox(void* viewer, const char* skyboxPath);
|
||||
void load_ibl(void* viewer, const char* iblPath);
|
||||
void remove_skybox(void* viewer);
|
||||
void remove_ibl(void* viewer);
|
||||
void* load_glb(void* viewer, const char* assetPath);
|
||||
void* load_gltf(void* viewer, const char* assetPath, const char* relativePath);
|
||||
bool set_camera(void* viewer, void* asset, const char* nodeName);
|
||||
void render(void* viewer);
|
||||
void destroy_swap_chain(void* viewer);
|
||||
void* get_renderer(void* viewer);
|
||||
void update_viewport_and_camera_projection(void* viewer, int width, int height, float scaleFactor);
|
||||
|
||||
void scroll(void* viewer, float x, float y , float z);
|
||||
|
||||
void grab_begin(void* viewer, int x, int y, bool pan);
|
||||
void grab_update(void* viewer, int x, int y);
|
||||
|
||||
void grab_end(void* viewer);
|
||||
|
||||
void apply_weights(void* asset, float* const weights, int count);
|
||||
|
||||
void animate_weights(void* asset, float* data, int numWeights, int numFrames, float frameRate);
|
||||
|
||||
void play_animation(void* asset, int index, bool loop);
|
||||
|
||||
int get_animation_count(void* asset);
|
||||
|
||||
void get_animation_name(void* asset, char* const outPtr, int index);
|
||||
|
||||
void get_target_name(void* asset, const char* meshName, char* const outPtr, int index );
|
||||
|
||||
int get_target_name_count(void* asset, const char* meshName);
|
||||
|
||||
void remove_asset(void* viewer, void* asset);
|
||||
|
||||
void clear_assets(void* viewer);
|
||||
|
||||
void set_texture(void* asset, const char* assetPath, int renderableIndex);
|
||||
|
||||
void transform_to_unit_cube(void* asset);
|
||||
|
||||
void set_position(void* asset, float x, float y, float z);
|
||||
|
||||
void set_rotation(void* asset, float rads, float x, float y, float z);
|
||||
|
||||
#endif
|
||||
32
ios/Classes/PolyvoxFilamentIOSApi.cc
Normal file
32
ios/Classes/PolyvoxFilamentIOSApi.cc
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "PolyvoxFilamentApi.h"
|
||||
#include "FilamentViewer.hpp"
|
||||
#include "ResourceBuffer.hpp"
|
||||
#include "SceneResources.hpp"
|
||||
#include <functional>
|
||||
|
||||
using namespace polyvox;
|
||||
using namespace std;
|
||||
|
||||
extern "C" {
|
||||
using RawLoadType = ResourceBuffer(const char*, void* resource);
|
||||
using RawFreeType = void(uint32_t, void*);
|
||||
|
||||
void* filament_viewer_new_ios(void* pb, void* loadResource, void* freeResource, void* resources) {
|
||||
|
||||
FreeResource _freeResource = [=](uint32_t rid) {
|
||||
reinterpret_cast<RawFreeType*>(freeResource)(rid, resources);
|
||||
};
|
||||
|
||||
function<ResourceBuffer(const char*)> _loadResource = [=](const char* uri){
|
||||
auto cast = reinterpret_cast<RawLoadType*>(loadResource);
|
||||
return cast(uri, resources);
|
||||
};
|
||||
|
||||
auto viewer = new FilamentViewer(pb,_loadResource, _freeResource);
|
||||
|
||||
return (void*)viewer;
|
||||
}
|
||||
void create_swap_chain(void* viewer, void* texture) {
|
||||
((FilamentViewer*)viewer)->createSwapChain(texture);
|
||||
}
|
||||
}
|
||||
3
ios/Classes/PolyvoxFilamentIOSApi.h
Normal file
3
ios/Classes/PolyvoxFilamentIOSApi.h
Normal file
@@ -0,0 +1,3 @@
|
||||
void* filament_viewer_new_ios(void* texture, void* loadResource, void* freeResource, void* resources);
|
||||
|
||||
void create_swap_chain(void* viewer, void* texture);
|
||||
63
ios/Classes/PolyvoxFilamentPlugin.m
Normal file
63
ios/Classes/PolyvoxFilamentPlugin.m
Normal file
@@ -0,0 +1,63 @@
|
||||
#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
|
||||
|
||||
// - (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 %@", p);
|
||||
// exit(-1);
|
||||
// }
|
||||
|
||||
// NSData* buffer = [NSData dataWithContentsOfFile:nsPath];
|
||||
// void* cpy = malloc([buffer length]);
|
||||
// memcpy(cpy, [buffer bytes], [buffer length]); // can we avoid this copy somehow?
|
||||
// _resourceId++;
|
||||
// ResourceBuffer rbuf(cpy, [buffer length], _resourceId);
|
||||
// return rbuf;
|
||||
// }
|
||||
|
||||
// - (void)freeResource:(ResourceBuffer)rb {
|
||||
// free((void*)rb.data);
|
||||
// }
|
||||
|
||||
// - (void)ready {
|
||||
// [_channel invokeMethod:@"ready" arguments:nil];
|
||||
// }
|
||||
|
||||
// - (NSMutableArray*) getAnimationNames {
|
||||
// unique_ptr<vector<string>> list = _viewer->getAnimationNames();
|
||||
// NSMutableArray* asArray = [NSMutableArray arrayWithCapacity:list->size()];
|
||||
// for(int i = 0; i < list->size(); i++) {
|
||||
// asArray[i] = [NSString stringWithFormat:@"%s", list->at(i).c_str()];
|
||||
// }
|
||||
// return asArray;
|
||||
// }
|
||||
|
||||
// - (NSMutableArray*) getTargetNames:(NSString*) meshName {
|
||||
// unique_ptr<vector<string>> list = _viewer->getTargetNames([meshName UTF8String]);
|
||||
// NSMutableArray* asArray = [NSMutableArray arrayWithCapacity:list->size()];
|
||||
// for(int i = 0; i < list->size(); i++) {
|
||||
// asArray[i] = [NSString stringWithFormat:@"%s", list->at(i).c_str()];
|
||||
// }
|
||||
// return asArray;
|
||||
// }
|
||||
|
||||
// @end
|
||||
|
||||
// @end
|
||||
@@ -1,12 +0,0 @@
|
||||
#import "PolyvoxFilamentPlugin.h"
|
||||
#import "FilamentNativeViewFactory.h"
|
||||
|
||||
FilamentNativeViewFactory* factory;
|
||||
|
||||
@implementation PolyvoxFilamentPlugin
|
||||
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
|
||||
factory =
|
||||
[[FilamentNativeViewFactory alloc] initWithRegistrar:registrar];
|
||||
[registrar registerViewFactory:factory withId:@"app.polyvox.filament/filament_view"];
|
||||
}
|
||||
@end
|
||||
1
ios/Classes/SwiftPolyvoxFilamentPlugin-Bridging-Header.h
Normal file
1
ios/Classes/SwiftPolyvoxFilamentPlugin-Bridging-Header.h
Normal file
@@ -0,0 +1 @@
|
||||
#import "PolyvoxFilamentApi.h"
|
||||
283
ios/Classes/SwiftPolyvoxFilamentPlugin.swift
Normal file
283
ios/Classes/SwiftPolyvoxFilamentPlugin.swift
Normal file
@@ -0,0 +1,283 @@
|
||||
import Flutter
|
||||
import UIKit
|
||||
import OpenGLES.ES3
|
||||
import GLKit
|
||||
|
||||
|
||||
public class SwiftPolyvoxFilamentPlugin: NSObject, FlutterPlugin, FlutterTexture {
|
||||
|
||||
var registrar : FlutterPluginRegistrar
|
||||
var textureId: Int64?
|
||||
var registry: FlutterTextureRegistry
|
||||
|
||||
var width: Double = 0
|
||||
var height: Double = 0
|
||||
|
||||
var context: EAGLContext?;
|
||||
var targetPixelBuffer: CVPixelBuffer?;
|
||||
var textureCache: CVOpenGLESTextureCache?;
|
||||
var texture: CVOpenGLESTexture? = nil;
|
||||
var frameBuffer: GLuint = 0;
|
||||
|
||||
|
||||
var pixelBufferAttrs = [
|
||||
kCVPixelBufferPixelFormatTypeKey: NSNumber(value: kCVPixelFormatType_32BGRA),
|
||||
kCVPixelBufferOpenGLCompatibilityKey: kCFBooleanTrue,
|
||||
kCVPixelBufferOpenGLESCompatibilityKey: kCFBooleanTrue,
|
||||
kCVPixelBufferIOSurfacePropertiesKey: [:]
|
||||
] as CFDictionary
|
||||
|
||||
var resources:NSMutableDictionary = [:]
|
||||
var viewer:UnsafeMutableRawPointer? = nil
|
||||
|
||||
var displayLink:CADisplayLink? = nil
|
||||
|
||||
static var messenger : FlutterBinaryMessenger? = nil;
|
||||
|
||||
var loadResourcePtr: UnsafeMutableRawPointer? = nil
|
||||
var freeResourcePtr: UnsafeMutableRawPointer? = nil
|
||||
var resourcesPtr : UnsafeMutableRawPointer? = nil
|
||||
|
||||
var loadResource : @convention(c) (UnsafeRawPointer, UnsafeMutableRawPointer) -> ResourceBuffer = { uri, resourcesPtr in
|
||||
print("Loading resource buffer")
|
||||
|
||||
let instance:SwiftPolyvoxFilamentPlugin = Unmanaged<SwiftPolyvoxFilamentPlugin>.fromOpaque(resourcesPtr).takeUnretainedValue()
|
||||
|
||||
let uriString = String(cString:uri.assumingMemoryBound(to: UInt8.self))
|
||||
|
||||
let key = instance.registrar.lookupKey(forAsset:uriString)
|
||||
|
||||
let path = Bundle.main.path(forResource: key, ofType:nil)
|
||||
do {
|
||||
let foo: String = path!
|
||||
let data = try Data(contentsOf: URL(fileURLWithPath:foo))
|
||||
let resId = instance.resources.count
|
||||
let nsData = data as NSData
|
||||
instance.resources[resId] = nsData
|
||||
let rawPtr = nsData.bytes
|
||||
return ResourceBuffer(data:rawPtr, size:UInt32(nsData.count), id:UInt32(resId))
|
||||
} catch {
|
||||
print("Error opening file: \(error)")
|
||||
return ResourceBuffer()
|
||||
}
|
||||
return ResourceBuffer()
|
||||
}
|
||||
|
||||
var freeResource : @convention(c) (UInt32,UnsafeMutableRawPointer) -> () = { rid, resourcesPtr in
|
||||
let instance:SwiftPolyvoxFilamentPlugin = Unmanaged<SwiftPolyvoxFilamentPlugin>.fromOpaque(resourcesPtr).takeUnretainedValue()
|
||||
instance.resources.removeObject(forKey:rid)
|
||||
}
|
||||
|
||||
func createDisplayLink() {
|
||||
displayLink = CADisplayLink(target: self,
|
||||
selector: #selector(doRender))
|
||||
|
||||
displayLink!.add(to: .current, forMode: RunLoop.Mode.default)
|
||||
}
|
||||
|
||||
@objc func doRender() {
|
||||
if(viewer != nil) {
|
||||
render(viewer)
|
||||
self.registry.textureFrameAvailable(self.textureId!)
|
||||
}
|
||||
}
|
||||
|
||||
public func copyPixelBuffer() -> Unmanaged<CVPixelBuffer>? {
|
||||
if(targetPixelBuffer == nil) {
|
||||
print("empty")
|
||||
return nil;
|
||||
}
|
||||
return Unmanaged.passRetained(targetPixelBuffer!);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static func register(with registrar: FlutterPluginRegistrar) {
|
||||
let _messenger = registrar.messenger();
|
||||
messenger = _messenger;
|
||||
let channel = FlutterMethodChannel(name: "app.polyvox.filament/event", binaryMessenger: _messenger)
|
||||
let instance = SwiftPolyvoxFilamentPlugin(textureRegistry: registrar.textures(), registrar:registrar)
|
||||
registrar.addMethodCallDelegate(instance, channel: channel)
|
||||
}
|
||||
|
||||
init(textureRegistry: FlutterTextureRegistry, registrar:FlutterPluginRegistrar) {
|
||||
self.registry = textureRegistry;
|
||||
self.registrar = registrar
|
||||
}
|
||||
|
||||
private func createPixelBuffer(width:Int, height:Int) {
|
||||
|
||||
if(targetPixelBuffer != nil) {
|
||||
destroy_swap_chain(self.viewer)
|
||||
}
|
||||
if(CVPixelBufferCreate(kCFAllocatorDefault, Int(width), Int(height),
|
||||
kCVPixelFormatType_32BGRA, pixelBufferAttrs, &targetPixelBuffer) != kCVReturnSuccess) {
|
||||
print("Error allocating pixel buffer")
|
||||
}
|
||||
if(self.viewer != nil) {
|
||||
create_swap_chain(self.viewer, unsafeBitCast(targetPixelBuffer!, to: UnsafeMutableRawPointer.self))
|
||||
update_viewport_and_camera_projection(self.viewer!, Int32(width), Int32(height), 1.0);
|
||||
}
|
||||
|
||||
print("Pixel buffer created")
|
||||
}
|
||||
|
||||
private func initialize(width:Int32, height:Int32) {
|
||||
|
||||
createPixelBuffer(width:Int(width), height:Int(height))
|
||||
self.textureId = self.registry.register(self)
|
||||
|
||||
loadResourcePtr = unsafeBitCast(loadResource, to: UnsafeMutableRawPointer.self)
|
||||
freeResourcePtr = unsafeBitCast(freeResource, to: UnsafeMutableRawPointer.self)
|
||||
|
||||
viewer = filament_viewer_new_ios(
|
||||
unsafeBitCast(targetPixelBuffer!, to: UnsafeMutableRawPointer.self),
|
||||
loadResourcePtr!,
|
||||
freeResourcePtr!,
|
||||
Unmanaged.passUnretained(self).toOpaque()
|
||||
)
|
||||
|
||||
update_viewport_and_camera_projection(self.viewer!, Int32(width), Int32(height), 1.0);
|
||||
|
||||
createDisplayLink()
|
||||
|
||||
}
|
||||
|
||||
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||||
let methodName = call.method;
|
||||
|
||||
switch methodName {
|
||||
case "initialize":
|
||||
let args = call.arguments as! Array<Int32>
|
||||
initialize(width:args[0], height:args[1])
|
||||
result(self.textureId);
|
||||
case "setBackgroundImage":
|
||||
let uri = call.arguments as! String
|
||||
set_background_image(self.viewer!, uri)
|
||||
render(self.viewer!)
|
||||
self.registry.textureFrameAvailable(self.textureId!)
|
||||
result("OK")
|
||||
case "resize":
|
||||
let args = call.arguments as! Array<Double>
|
||||
let width = Int(args[0])
|
||||
let height = Int(args[1])
|
||||
createPixelBuffer(width: width, height:height)
|
||||
result("OK")
|
||||
case "loadSkybox":
|
||||
load_skybox(self.viewer!, call.arguments as! String)
|
||||
result("OK");
|
||||
case "removeSkybox":
|
||||
remove_skybox(self.viewer!)
|
||||
result("OK");
|
||||
case "loadGlb":
|
||||
let assetPtr = load_glb(self.viewer, call.arguments as! String)
|
||||
result(unsafeBitCast(assetPtr, to:Int64.self));
|
||||
case "loadGltf":
|
||||
let args = call.arguments as! Array<Any?>
|
||||
result(load_gltf(self.viewer, args[0] as! String, args[1] as! String));
|
||||
case "removeAsset":
|
||||
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: call.arguments as! Int)
|
||||
remove_asset(viewer!, assetPtr)
|
||||
result("OK")
|
||||
case "clearAssets":
|
||||
clear_assets(viewer!)
|
||||
result("OK")
|
||||
case "loadIbl":
|
||||
load_ibl(self.viewer, call.arguments as! String)
|
||||
result("OK");
|
||||
case "removeIbl":
|
||||
remove_ibl(self.viewer)
|
||||
result("OK");
|
||||
case "setCamera":
|
||||
let args = call.arguments as! Array<Any?>
|
||||
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int)
|
||||
set_camera(self.viewer, assetPtr, args[1] as! String)
|
||||
result("OK");
|
||||
case "playAnimation":
|
||||
let args = call.arguments as! Array<Any?>
|
||||
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int)
|
||||
let animationIndex = args[1] as! Int32;
|
||||
let loop = args[2] as! Bool;
|
||||
play_animation(assetPtr, animationIndex, loop)
|
||||
result("OK");
|
||||
case "stopAnimation":
|
||||
let args = call.arguments as! Array<Any?>
|
||||
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int)
|
||||
let animationIndex = args[1] as! Int32
|
||||
// stop_animation(assetPtr, animationIndex) // TODO
|
||||
result("OK");
|
||||
case "getTargetNames":
|
||||
let args = call.arguments as! Array<Any?>
|
||||
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int)
|
||||
let meshName = args[1] as! String
|
||||
let numNames = get_target_name_count(assetPtr, meshName)
|
||||
var names = [String]()
|
||||
for i in 0...numNames - 1{
|
||||
let outPtr = UnsafeMutablePointer<CChar>.allocate(capacity:256)
|
||||
get_target_name(assetPtr, meshName, outPtr, i)
|
||||
names.append(String(cString:outPtr))
|
||||
}
|
||||
result(names);
|
||||
case "getAnimationNames":
|
||||
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: call.arguments as! Int)
|
||||
let numNames = get_animation_count(assetPtr)
|
||||
var names = [String]()
|
||||
for i in 0...numNames - 1{
|
||||
let outPtr = UnsafeMutablePointer<CChar>.allocate(capacity:256)
|
||||
get_animation_name(assetPtr, outPtr, i)
|
||||
names.append(String(cString:outPtr))
|
||||
}
|
||||
result(names);
|
||||
case "applyWeights":
|
||||
let args = call.arguments as! Array<Any?>
|
||||
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int)
|
||||
let weights = args[1] as! Array<Double>
|
||||
weights.map { Float($0) }.withUnsafeBufferPointer {
|
||||
apply_weights(assetPtr, UnsafeMutablePointer<Float>.init(mutating:$0.baseAddress), Int32(weights.count))
|
||||
|
||||
}
|
||||
result("OK")
|
||||
case "zoom":
|
||||
let args = call.arguments as! Array<Any?>
|
||||
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int)
|
||||
let factor = args[1] as! Double
|
||||
scroll(assetPtr, 0,0, Float(factor))
|
||||
result("OK")
|
||||
case "animateWeights":
|
||||
let args = call.arguments as! Array<Any?>
|
||||
let assetPtr = UnsafeMutableRawPointer.init(bitPattern: args[0] as! Int)
|
||||
let frameData = args[1] as! Array<Double>
|
||||
let numWeights = args[2] as! Int
|
||||
let numFrames = args[3] as! Int
|
||||
let frameLenInMs = args[4] as! Double
|
||||
frameData.map { Float($0)}.withUnsafeBufferPointer {
|
||||
animate_weights(assetPtr, UnsafeMutablePointer<Float>.init(mutating:$0.baseAddress), Int32(numWeights), Int32(numFrames), Float(frameLenInMs))
|
||||
}
|
||||
result("OK")
|
||||
default:
|
||||
result(FlutterMethodNotImplemented)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// } else if([@"panStart" isEqualToString:call.method]) {
|
||||
// _viewer->manipulator->grabBegin([call.arguments[0] intValue], [call.arguments[1] intValue], true);
|
||||
// result(@"OK");
|
||||
// } else if([@"panUpdate" isEqualToString:call.method]) {
|
||||
// _viewer->manipulator->grabUpdate([call.arguments[0] intValue], [call.arguments[1] intValue]);
|
||||
// result(@"OK");
|
||||
// } else if([@"panEnd" isEqualToString:call.method]) {
|
||||
// _viewer->manipulator->grabEnd();
|
||||
// result(@"OK");
|
||||
// } else if([@"rotateStart" isEqualToString:call.method]) {
|
||||
// _viewer->manipulator->grabBegin([call.arguments[0] intValue], [call.arguments[1] intValue], false);
|
||||
// result(@"OK");
|
||||
// } else if([@"rotateUpdate" isEqualToString:call.method]) {
|
||||
// _viewer->manipulator->grabUpdate([call.arguments[0] intValue], [call.arguments[1] intValue]);
|
||||
// result(@"OK");
|
||||
// } else if([@"rotateEnd" isEqualToString:call.method]) {
|
||||
// _viewer->manipulator->grabEnd();
|
||||
// result(@"OK");
|
||||
// } else
|
||||
@@ -13,7 +13,7 @@ A new flutter plugin project.
|
||||
s.license = { :file => '../LICENSE' }
|
||||
s.author = { 'Your Company' => 'email@example.com' }
|
||||
s.source = { :path => '.' }
|
||||
s.source_files = 'Classes/**/*', 'src/*.*', 'src/morph/*.*', 'src/morph/UbershaderLoader.cpp' #, "include/**/*"
|
||||
s.source_files = 'Classes/**/*', 'src/ResourceBuffer.hpp', 'src/FilamentViewer.cpp', 'src/SceneAsset.cpp', 'src/SceneAssetLoader.cpp', 'src/StreamBufferAdapter.cpp', 'src/image/imagematerial.c', 'src/image/imagematerials_ios.c'
|
||||
#s.header_dir = "include"
|
||||
#s.header_mappings_dir = "include"
|
||||
s.dependency 'Flutter'
|
||||
@@ -23,26 +23,27 @@ A new flutter plugin project.
|
||||
|
||||
s.library = "c++"
|
||||
|
||||
s.user_target_xcconfig = {
|
||||
'DEFINES_MODULE' => 'YES',
|
||||
'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386',
|
||||
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
|
||||
'OTHER_CXXFLAGS' => '"--std=c++17" "-fmodules" "-fcxx-modules" "$(inherited)"',
|
||||
'USER_HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/include" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/src" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/src/image "$(inherited)"',
|
||||
'ALWAYS_SEARCH_USER_PATHS' => 'YES',
|
||||
"OTHER_LDFLAGS" => '-lfilament -lbackend -lfilameshio -lviewer -lfilamat -lgeometry -lutils -lfilabridge -lgltfio_core -lfilament-iblprefilter -limage -lcamutils -lgltfio_core -lfilaflat -ldracodec -libl -lktxreader -limageio -lpng -lpng16 -ltinyexr -lz -lstb -luberzlib -lsmol-v -luberarchive -lzstd',
|
||||
'LIBRARY_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/lib" "$(inherited)"',
|
||||
}
|
||||
|
||||
|
||||
# Flutter.framework does not contain a i386 slice.
|
||||
# s.user_target_xcconfig = {
|
||||
# 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
|
||||
# 'ALWAYS_SEARCH_USER_PATHS' => 'YES',
|
||||
# 'USER_HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/include" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/src", "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/morph" "$(inherited)"',
|
||||
# 'OTHER_CXXFLAGS' => '"--std=c++17" "-fmodules" "-fcxx-modules" "$(inherited)"',
|
||||
# "CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
|
||||
# #"CLANG_CXX_LIBRARY" => "libc++"
|
||||
# "OTHER_LDFLAGS" => '-lfilament -lbackend -lfilameshio -lviewer -lfilamat -lgeometry -lutils -lfilabridge -lgltfio_resources_lite -lgltfio_core -lfilament-iblprefilter -limage -lcamutils -lgltfio_resources -lfilaflat -ldracodec -libl',
|
||||
# 'LIBRARY_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/lib" "$(inherited)"',
|
||||
# }
|
||||
s.pod_target_xcconfig = {
|
||||
'DEFINES_MODULE' => 'YES',
|
||||
'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386',
|
||||
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
|
||||
'OTHER_CXXFLAGS' => '"--std=c++17" "-fmodules" "-fcxx-modules" "$(inherited)"',
|
||||
'USER_HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/include" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/src", "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/morph" "$(inherited)"',
|
||||
'USER_HEADER_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/include" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/src" "${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/src/image "$(inherited)"',
|
||||
'ALWAYS_SEARCH_USER_PATHS' => 'YES',
|
||||
"OTHER_LDFLAGS" => '-lfilament -lbackend -lfilameshio -lviewer -lfilamat -lgeometry -lutils -lfilabridge -lgltfio_resources_lite -lgltfio_core -lfilament-iblprefilter -limage -lcamutils -lgltfio_resources -lfilaflat -ldracodec -libl',
|
||||
"OTHER_LDFLAGS" => '-lfilament -lbackend -lfilameshio -lviewer -lfilamat -lgeometry -lutils -lfilabridge -lgltfio_core -lfilament-iblprefilter -limage -lcamutils -lgltfio_core -lfilaflat -ldracodec -libl -lktxreader -limageio -lpng -lpng16 -ltinyexr -lz -lstb -luberzlib -lsmol-v -luberarchive -lzstd',
|
||||
'LIBRARY_SEARCH_PATHS' => '"${PODS_ROOT}/../.symlinks/plugins/polyvox_filament/ios/lib" "$(inherited)"',
|
||||
}
|
||||
|
||||
|
||||
44
ios/src/ResourceBuffer.hpp
Normal file
44
ios/src/ResourceBuffer.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef RESOURCE_BUFFER_H
|
||||
#define RESOURCE_BUFFER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
//
|
||||
// Pairs a memory buffer with an ID that can be used to unload the backing asset if needed.
|
||||
// Use this when you want to load an asset from a resource that requires more than just `free` on the underlying buffer.
|
||||
// e.g.
|
||||
// ```
|
||||
// uint64_t id = get_next_resource_id();
|
||||
// AAsset *asset = AAssetManager_open(am, name, AASSET_MODE_BUFFER);
|
||||
// off_t length = AAsset_getLength(asset);
|
||||
// const void * buffer = AAsset_getBuffer(asset);
|
||||
// uint8_t *buf = new uint8_t[length ];
|
||||
// memcpy(buf,buffer, length);
|
||||
// ResourceBuffer rb(buf, length, id);
|
||||
// ...
|
||||
// ...
|
||||
// (elsewhere)
|
||||
// AAsset* asset = get_asset_from_id(rb.id);
|
||||
// AAsset_close(asset);
|
||||
// free_asset_id(rb.id);
|
||||
//
|
||||
struct ResourceBuffer {
|
||||
#if defined(__cplusplus)
|
||||
ResourceBuffer(const void* data, const uint32_t size, const uint32_t id) : data(data), size(size), id(id) {};
|
||||
ResourceBuffer& operator=(ResourceBuffer other) {
|
||||
data = other.data;
|
||||
size = other.size;
|
||||
id = other.id;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
const void* data;
|
||||
uint32_t size;
|
||||
uint32_t id;
|
||||
};
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -139,7 +139,7 @@ void SceneAsset::setTexture(const char* resourcePath, int renderableIndex) {
|
||||
|
||||
delete inputStream;
|
||||
|
||||
_freeResource(imageResource);
|
||||
_freeResource(imageResource.id);
|
||||
|
||||
uint32_t channels = image->getChannels();
|
||||
uint32_t w = image->getWidth();
|
||||
|
||||
@@ -52,7 +52,7 @@ SceneAsset *SceneAssetLoader::fromGltf(const char *uri,
|
||||
|
||||
ResourceLoader::BufferDescriptor b(buf.data, buf.size);
|
||||
_resourceLoader->addResourceData(resourceUris[i], std::move(b));
|
||||
_freeResource(buf);
|
||||
_freeResource(buf.id);
|
||||
}
|
||||
|
||||
_resourceLoader->loadResources(asset);
|
||||
@@ -115,7 +115,7 @@ SceneAsset *SceneAssetLoader::fromGlb(const char *uri) {
|
||||
asset->releaseSourceData();
|
||||
Log("Source data released.");
|
||||
|
||||
_freeResource(rbuf);
|
||||
_freeResource(rbuf.id);
|
||||
|
||||
Log("Successfully loaded GLB.");
|
||||
return new SceneAsset(asset, _engine, _ncm, _loadResource, _freeResource);
|
||||
@@ -128,4 +128,4 @@ void SceneAssetLoader::remove(SceneAsset *asset) {
|
||||
_assetLoader->destroyAsset(asset->_asset);
|
||||
delete asset;
|
||||
}
|
||||
} // namespace polyvox
|
||||
} // namespace polyvox
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "SceneResources.hpp"
|
||||
#include "SceneAsset.hpp"
|
||||
#include "ResourceBuffer.hpp"
|
||||
|
||||
namespace polyvox {
|
||||
using namespace filament;
|
||||
|
||||
@@ -1,52 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include "ResourceBuffer.hpp"
|
||||
|
||||
namespace polyvox {
|
||||
|
||||
//
|
||||
// Pairs a memory buffer with an ID that can be used to unload the backing asset if needed.
|
||||
// Use this when you want to load an asset from a resource that requires more than just `free` on the underlying buffer.
|
||||
// e.g.
|
||||
// ```
|
||||
// uint64_t id = get_next_resource_id();
|
||||
// AAsset *asset = AAssetManager_open(am, name, AASSET_MODE_BUFFER);
|
||||
// off_t length = AAsset_getLength(asset);
|
||||
// const void * buffer = AAsset_getBuffer(asset);
|
||||
// uint8_t *buf = new uint8_t[length ];
|
||||
// memcpy(buf,buffer, length);
|
||||
// ResourceBuffer rb(buf, length, id);
|
||||
// ...
|
||||
// ...
|
||||
// (elsewhere)
|
||||
// AAsset* asset = get_asset_from_id(rb.id);
|
||||
// AAsset_close(asset);
|
||||
// free_asset_id(rb.id);
|
||||
//
|
||||
struct ResourceBuffer {
|
||||
ResourceBuffer(const void* data, const uint32_t size, const uint32_t id) : data(data), size(size), id(id) {};
|
||||
|
||||
ResourceBuffer& operator=(ResourceBuffer other)
|
||||
{
|
||||
data = other.data;
|
||||
size = other.size;
|
||||
id = other.id;
|
||||
return *this;
|
||||
}
|
||||
const void* data;
|
||||
uint32_t size;
|
||||
uint32_t id;
|
||||
};
|
||||
|
||||
using namespace std;
|
||||
//
|
||||
// Typedef for any function that loads a resource into a ResourceBuffer from an asset URI.
|
||||
// Typedef for a function that loads a resource into a ResourceBuffer from an asset URI.
|
||||
//
|
||||
using LoadResource = std::function<ResourceBuffer(const char* uri)>;
|
||||
using LoadResource = function<ResourceBuffer(const char* uri)>;
|
||||
|
||||
//
|
||||
// Typedef for any function that frees a ResourceBuffer.
|
||||
// Typedef for a function that frees an ID associated with a ResourceBuffer.
|
||||
//
|
||||
using FreeResource = std::function<void (ResourceBuffer)>;
|
||||
using FreeResource = function<void (uint32_t)>;
|
||||
|
||||
typedef std::chrono::time_point<std::chrono::high_resolution_clock> time_point_t;
|
||||
|
||||
@@ -110,4 +79,5 @@ namespace polyvox {
|
||||
float* frameData;
|
||||
int numWeights;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user