From 908c76d6c3f70e37ea6cb02c9613e9ee0fb657a6 Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Wed, 27 Sep 2023 14:21:31 +0800 Subject: [PATCH 1/2] make iOS/MacOS consistent re moveCameraToBoundingBox --- ios/src/FilamentViewer.cpp | 12 +++++++----- ios/src/PolyvoxFilamentApi.cpp | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/ios/src/FilamentViewer.cpp b/ios/src/FilamentViewer.cpp index 9e759d60..ac9bb435 100644 --- a/ios/src/FilamentViewer.cpp +++ b/ios/src/FilamentViewer.cpp @@ -872,17 +872,19 @@ void FilamentViewer::setCameraPosition(float x, float y, float z) { void FilamentViewer::moveCameraToAsset(EntityId entityId) { - auto asset = _assetManager->getAssetByEntityId(entityId); +auto asset = _assetManager->getAssetByEntityId(entityId); if(!asset) { Log("Failed to find asset attached to specified entity id."); return; } - const filament::Aabb bb = asset->mAsset->getBoundingBox(); + const filament::Aabb bb = asset->getBoundingBox(); + auto corners = bb.getCorners(); Camera& cam =_view->getCamera(); - _cameraPosition = math::mat4f::translation(bb.getCorners()); - _cameraRotation = math::mat4f(); - cam.setModelMatrix(_cameraPosition * _cameraRotation); + auto eye = corners.vertices[0] * 1.5; + auto lookAt = corners.vertices[7]; + cam.lookAt(eye, lookAt); + Log("Moved camera to %f %f %f, lookAt %f %f %f, near %f far %f", eye[0], eye[1], eye[2], lookAt[0], lookAt[1], lookAt[2], cam.getNear(), cam.getCullingFar()); } void FilamentViewer::setCameraRotation(float rads, float x, float y, float z) { diff --git a/ios/src/PolyvoxFilamentApi.cpp b/ios/src/PolyvoxFilamentApi.cpp index d90c9395..182daac0 100644 --- a/ios/src/PolyvoxFilamentApi.cpp +++ b/ios/src/PolyvoxFilamentApi.cpp @@ -98,7 +98,7 @@ extern "C" { } FLUTTER_PLUGIN_EXPORT void move_camera_to_asset(const void* const viewer, EntityId asset) { - ((FilamentViewer*)viewer)->moveCameraToAsset(asset, asset); + ((FilamentViewer*)viewer)->moveCameraToAsset(asset); } FLUTTER_PLUGIN_EXPORT void set_camera_focus_distance(const void* const viewer, float distance) { From 93cb9a1307f086f1aceafb49edcbda0daa129b96 Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Wed, 27 Sep 2023 14:21:53 +0800 Subject: [PATCH 2/2] fix surface init on Android --- android/src/main/cpp/FilamentAndroid.cpp | 19 +- .../app/polyvox/filament/FilamentInterop.kt | 12 +- .../polyvox/filament/PolyvoxFilamentPlugin.kt | 240 +++++++++--------- 3 files changed, 126 insertions(+), 145 deletions(-) diff --git a/android/src/main/cpp/FilamentAndroid.cpp b/android/src/main/cpp/FilamentAndroid.cpp index 7353f04b..3f69df0d 100644 --- a/android/src/main/cpp/FilamentAndroid.cpp +++ b/android/src/main/cpp/FilamentAndroid.cpp @@ -3,24 +3,11 @@ extern "C" { - #include "PolyvoxFilamentApi.h" - - const void* create_filament_viewer_android( - jobject surface, JNIEnv* env, ResourceLoaderWrapper* loaderWrapper - ) { - ANativeWindow* window = ANativeWindow_fromSurface(env, surface); - return create_filament_viewer(window,loaderWrapper); - } - - void create_swap_chain_android( - const void* const viewer, + void* get_native_window_from_surface( jobject surface, - JNIEnv* env, - uint32_t width, - uint32_t height + JNIEnv* env ) { - ANativeWindow* window = ANativeWindow_fromSurface(env, surface); - create_swap_chain(viewer, window, width, height); + return ANativeWindow_fromSurface(env, surface); } } diff --git a/android/src/main/kotlin/app/polyvox/filament/FilamentInterop.kt b/android/src/main/kotlin/app/polyvox/filament/FilamentInterop.kt index 9e6921d2..0d474b25 100644 --- a/android/src/main/kotlin/app/polyvox/filament/FilamentInterop.kt +++ b/android/src/main/kotlin/app/polyvox/filament/FilamentInterop.kt @@ -26,15 +26,9 @@ interface FreeResourceFromOwner : Callback { } interface FilamentInterop : Library { +fun create_filament_viewer(context:Pointer, loader:Pointer) : Pointer; fun create_swap_chain(viewer: Pointer, window:Pointer?, width:Int, height:Int); - -fun create_swap_chain_android(viewer: Pointer, surface:Object, - env:JNIEnv, width:Int, height:Int); -fun create_filament_viewer_android( - surface:Object, - env:JNIEnv, - resourceLoader:Pointer -) : Pointer; +fun get_native_window_from_surface(surface:Object, env:JNIEnv) : Pointer; fun delete_filament_viewer(viewer: Any?) fun get_asset_manager(viewer: Any?): Any? fun create_render_target(viewer: Any?, texture_id: Int, width: Int, height: Int) @@ -95,8 +89,6 @@ fun set_camera_focus_distance(viewer: Any?, focus_distance: Float) fun hide_mesh(asset_manager: Any?, asset: EntityId, mesh_name: String): Int fun reveal_mesh(asset_manager: Any?, asset: EntityId, mesh_name: String): Int fun ios_dummy() -fun create_filament_viewer(context:Long, loader:Pointer) : Pointer; - fun make_resource_loader(loadResourceFromOwner: LoadResourceFromOwner, freeResource: FreeResourceFromOwner, owner:Pointer?) : Pointer; } diff --git a/android/src/main/kotlin/app/polyvox/filament/PolyvoxFilamentPlugin.kt b/android/src/main/kotlin/app/polyvox/filament/PolyvoxFilamentPlugin.kt index a5724ff4..c9ce8bde 100644 --- a/android/src/main/kotlin/app/polyvox/filament/PolyvoxFilamentPlugin.kt +++ b/android/src/main/kotlin/app/polyvox/filament/PolyvoxFilamentPlugin.kt @@ -99,114 +99,114 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Lo Log.e("polyvox_filament", call.method, null) when (call.method) { "createTexture" -> { - if(_glTextureId != 0) { - result.success(_glTextureId) - return - } - if(_glContext == null) { - _glContext = EGL14.eglGetCurrentContext() - if (_glContext == EGL14.EGL_NO_CONTEXT) { +// if(_glTextureId != 0) { +// result.success(_glTextureId) +// return +// } +// if(_glContext == null) { +// _glContext = EGL14.eglGetCurrentContext() +// if (_glContext == EGL14.EGL_NO_CONTEXT) { - // if(surfaceTextureEntry != null) { - // result.error("ERR", "Surface texture already exists. Call destroyTexture before creating a new one", null); - // } else { - // surface = Surface(surfaceTextureEntry!!.surfaceTexture()) +// // if(surfaceTextureEntry != null) { +// // result.error("ERR", "Surface texture already exists. Call destroyTexture before creating a new one", null); +// // } else { +// // surface = Surface(surfaceTextureEntry!!.surfaceTexture()) - // if(!surface!!.isValid) { - // result.error("ERR", "Surface creation failed. ", null); - // } else { - // result.success(surfaceTextureEntry!!.id().toInt()) - // } - // } +// // if(!surface!!.isValid) { +// // result.error("ERR", "Surface creation failed. ", null); +// // } else { +// // result.success(surfaceTextureEntry!!.id().toInt()) +// // } +// // } - mEglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY) - if (mEglDisplay == EGL14.EGL_NO_DISPLAY) { - result.error("Err", "eglGetDisplay failed", null); - return; - } +// mEglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY) +// if (mEglDisplay == EGL14.EGL_NO_DISPLAY) { +// result.error("Err", "eglGetDisplay failed", null); +// return; +// } - val version = IntArray(2) +// val version = IntArray(2) - if (!EGL14.eglInitialize(mEglDisplay, version, 0, version, 1)) { - var error = EGL14.eglGetError(); - Log.e("DISPLAY_FAILED", "NativeEngine: failed to init display %d"); - } +// if (!EGL14.eglInitialize(mEglDisplay, version, 0, version, 1)) { +// var error = EGL14.eglGetError(); +// Log.e("DISPLAY_FAILED", "NativeEngine: failed to init display %d"); +// } - val attribs = intArrayOf( - EGL14.EGL_RENDERABLE_TYPE, EGL15.EGL_OPENGL_ES3_BIT, - EGL14.EGL_SURFACE_TYPE, EGL14.EGL_WINDOW_BIT, - EGL14.EGL_BLUE_SIZE, 8, - EGL14.EGL_GREEN_SIZE, 8, - EGL14.EGL_RED_SIZE, 8, - EGL14.EGL_DEPTH_SIZE, 16, - EGL14.EGL_NONE); - var numConfigs = intArrayOf(1) - val configs: Array = arrayOf(null) +// val attribs = intArrayOf( +// EGL14.EGL_RENDERABLE_TYPE, EGL15.EGL_OPENGL_ES3_BIT, +// EGL14.EGL_SURFACE_TYPE, EGL14.EGL_WINDOW_BIT, +// EGL14.EGL_BLUE_SIZE, 8, +// EGL14.EGL_GREEN_SIZE, 8, +// EGL14.EGL_RED_SIZE, 8, +// EGL14.EGL_DEPTH_SIZE, 16, +// EGL14.EGL_NONE); +// var numConfigs = intArrayOf(1) +// val configs: Array = arrayOf(null) - if(!EGL14.eglChooseConfig(mEglDisplay, attribs, 0, configs, 0, 1, numConfigs, 0)) { - result.error("NO_GL_CONTEXT", "Failed to get matching EGLConfig", null); - return; - } +// if(!EGL14.eglChooseConfig(mEglDisplay, attribs, 0, configs, 0, 1, numConfigs, 0)) { +// result.error("NO_GL_CONTEXT", "Failed to get matching EGLConfig", null); +// return; +// } - _glContext = EGL14.eglCreateContext(mEglDisplay, configs[0]!!, EGL14.EGL_NO_CONTEXT, intArrayOf(EGL14.EGL_CONTEXT_CLIENT_VERSION, 3, EGL14.EGL_NONE), 0); +// _glContext = EGL14.eglCreateContext(mEglDisplay, configs[0]!!, EGL14.EGL_NO_CONTEXT, intArrayOf(EGL14.EGL_CONTEXT_CLIENT_VERSION, 3, EGL14.EGL_NONE), 0); - if (_glContext === EGL14.EGL_NO_CONTEXT || EGL14.eglMakeCurrent(mEglDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, _glContext) == false) { - result.error("NO_GL_CONTEXT", "Failed to get current OpenGL context", null); - return; - }; - Log.i("polyvox_filament", "Successfully created OpenGL context"); - } - } +// if (_glContext === EGL14.EGL_NO_CONTEXT || EGL14.eglMakeCurrent(mEglDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, _glContext) == false) { +// result.error("NO_GL_CONTEXT", "Failed to get current OpenGL context", null); +// return; +// }; +// Log.i("polyvox_filament", "Successfully created OpenGL context"); +// } +// } - val args = call.arguments as List<*> - val width = 256 //args[0] as Double - val height = 256// args[1] as Double - if(width <1 || height < 1) { - result.error("DIMENSION_MISMATCH","Both dimensions must be greater than zero", null); - return; - } - Log.i("polyvox_filament", "Creating texture of size ${width}x${height}"); - val texture = IntArray(1) - GLES32.glGenTextures(1, texture, 0) - _glTextureId = texture[0] + val args = call.arguments as List<*> + val width = 256 //args[0] as Double + val height = 256// args[1] as Double + if(width <1 || height < 1) { + result.error("DIMENSION_MISMATCH","Both dimensions must be greater than zero", null); + return; + } + Log.i("polyvox_filament", "Creating texture of size ${width}x${height}"); +// val texture = IntArray(1) +// GLES32.glGenTextures(1, texture, 0) +// _glTextureId = texture[0] - GLES32.glBindTexture(GLES32.GL_TEXTURE_2D, _glTextureId) - GLES32.glTexParameteri(GLES32.GL_TEXTURE_2D, GLES32.GL_TEXTURE_MIN_FILTER, GLES32.GL_LINEAR) - GLES32.glTexParameteri(GLES32.GL_TEXTURE_2D, GLES32.GL_TEXTURE_MAG_FILTER, GLES32.GL_LINEAR) - GLES32.glTexParameteri(GLES32.GL_TEXTURE_2D, GLES32.GL_TEXTURE_WRAP_S, GLES32.GL_CLAMP_TO_EDGE) - GLES32.glTexParameteri(GLES32.GL_TEXTURE_2D, GLES32.GL_TEXTURE_WRAP_T, GLES32.GL_CLAMP_TO_EDGE) - GLES32.glTexImage2D( - GLES32.GL_TEXTURE_2D, - 0, - GLES32.GL_RGBA, - width.toInt(), - height.toInt(), - 0, - GLES32.GL_RGBA, - GLES32.GL_UNSIGNED_BYTE, - null - ) - if(_glTextureId == 0) { - result.error("GL_TEXTURE_CREATE_FAILED", "Failed to create OpenGL texture. Check logcat for details", null); - return; - } +// GLES32.glBindTexture(GLES32.GL_TEXTURE_2D, _glTextureId) +// GLES32.glTexParameteri(GLES32.GL_TEXTURE_2D, GLES32.GL_TEXTURE_MIN_FILTER, GLES32.GL_LINEAR) +// GLES32.glTexParameteri(GLES32.GL_TEXTURE_2D, GLES32.GL_TEXTURE_MAG_FILTER, GLES32.GL_LINEAR) +// GLES32.glTexParameteri(GLES32.GL_TEXTURE_2D, GLES32.GL_TEXTURE_WRAP_S, GLES32.GL_CLAMP_TO_EDGE) +// GLES32.glTexParameteri(GLES32.GL_TEXTURE_2D, GLES32.GL_TEXTURE_WRAP_T, GLES32.GL_CLAMP_TO_EDGE) +// GLES32.glTexImage2D( +// GLES32.GL_TEXTURE_2D, +// 0, +// GLES32.GL_RGBA, +// width.toInt(), +// height.toInt(), +// 0, +// GLES32.GL_RGBA, +// GLES32.GL_UNSIGNED_BYTE, +// null +// ) +// if(_glTextureId == 0) { +// result.error("GL_TEXTURE_CREATE_FAILED", "Failed to create OpenGL texture. Check logcat for details", null); +// return; +// } - _surfaceTexture = SurfaceTexture(_glTextureId) - _surfaceTexture!!.setDefaultBufferSize(width.toInt(), height.toInt()) - _surfaceTexture!!.setOnFrameAvailableListener({ - Log.i("TMP","FRAME AVAILABLE"); - }) - _surfaceTextureEntry = flutterPluginBinding.textureRegistry.registerSurfaceTexture(_surfaceTexture!!) +// _surfaceTexture = SurfaceTexture(_glTextureId) -// _surfaceTextureEntry = flutterPluginBinding.textureRegistry.createSurfaceTexture() -// _surfaceTexture = _surfaceTextureEntry!!.surfaceTexture(); +// _surfaceTexture!!.setOnFrameAvailableListener({ +// Log.i("TMP","FRAME AVAILABLE"); +// }) +// _surfaceTextureEntry = flutterPluginBinding.textureRegistry.registerSurfaceTexture(_surfaceTexture!!) + + _surfaceTextureEntry = flutterPluginBinding.textureRegistry.createSurfaceTexture() + _surfaceTexture = _surfaceTextureEntry!!.surfaceTexture(); + _surfaceTexture!!.setDefaultBufferSize(width.toInt(), height.toInt()) _surface = Surface(_surfaceTexture) - val canvas = _surface!!.lockHardwareCanvas() - canvas.drawColor(Color.GREEN) - _surface!!.unlockCanvasAndPost(canvas) -// result.success(_surfaceTextureEntry!!.id()) - result.success(0) + // val canvas = _surface!!.lockHardwareCanvas() + // canvas.drawColor(Color.GREEN) + // _surface!!.unlockCanvasAndPost(canvas) + result.success(_surfaceTextureEntry!!.id()) } "destroyTexture" -> { if (_viewer != null) { @@ -227,23 +227,22 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Lo result.success(true) } "resize" -> { - result.success(null) - return - if (_viewer == null) { result.error("VIEWER_NULL", "Error: cannot resize before a viewer has been created", null) return } + val wasRendering = _rendering; _rendering = false _lib.destroy_swap_chain(_viewer) val args = call.arguments as List - val width = args[0] as Int - val height = args[1] as Int - val scale = args[2] as Float + val width = 100 // args[0] as Int + val height = 100 // args[1] as Int + val scale = 1.0 // args[2] as Float _surfaceTexture!!.setDefaultBufferSize(width, height) - // _lib.create_swap_chain(Pointer.nativeValue(_viewer), Surface(_surfaceTexture), width, height) - _lib.update_viewport_and_camera_projection(_viewer!!, width as UInt, height as UInt, scale); - _rendering = true + val nativeWindow = _lib.get_native_window_from_surface(_surface!! as Object, JNIEnv.CURRENT) + _lib.create_swap_chain(_viewer!!, nativeWindow, width, height) + _lib.update_viewport_and_camera_projection(_viewer!!, width as UInt, height as UInt, scale.toFloat()) + _rendering = wasRendering; Log.i(TAG, "Resized to ${args[0]}x${args[1]}") result.success(_surfaceTexture) } @@ -254,20 +253,22 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Lo _viewer = null } val resourceLoader = _lib.make_resource_loader(this, this, Pointer(0)) -// _viewer = _lib.create_filament_viewer(0, resourceLoader); -// _viewer = _lib.create_filament_viewer_android(_surface!! as Object, JNIEnv.CURRENT, resourceLoader); -//surface. - _viewer = _lib.create_filament_viewer( - _glContext!!.nativeHandle, - resourceLoader) + val nativeWindow = _lib.get_native_window_from_surface(_surface!! as Object, JNIEnv.CURRENT) + _viewer = _lib.create_filament_viewer(nativeWindow, resourceLoader); + + // _viewer = _lib.create_filament_viewer( + // _glContext!!.nativeHandle, + // resourceLoader) val args = call.arguments as List -// val width = args[0] as Double -// val height = args[1] as Double - val width = 200 - val height = 200 -// _lib.create_swap_chain_android(_viewer!!, _surface!! as Object, JNIEnv.CURRENT, width.toInt(), height.toInt()) - _lib.create_swap_chain(_viewer!!, null, width.toInt(), height.toInt()) - _lib.create_render_target(_viewer, _glTextureId, width.toInt(),height.toInt()); + var width = 100.0 // args[0] as Double + val height = 100.0 // args[1] as Double +// if(width < 1 || height < 1) { +// result.error("DIMENSION_MISMATCH","Both dimensions must be greater than zero", null); +// return; +// } + _lib.create_swap_chain(_viewer!!, nativeWindow, width.toInt(), height.toInt()) + // _lib.create_swap_chain(_viewer!!, null, width.toInt(), height.toInt()) + // _lib.create_render_target(_viewer, _glTextureId, width.toInt(),height.toInt()); result.success(Pointer.nativeValue(_viewer!!)) } @@ -380,9 +381,9 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Lo result.success(true) } "render" -> { - val canvas = _surface!!.lockHardwareCanvas() - canvas.drawColor(Color.BLUE) - _surface!!.unlockCanvasAndPost(canvas) +// val canvas = _surface!!.lockHardwareCanvas() +// canvas.drawColor(Color.BLUE) +// _surface!!.unlockCanvasAndPost(canvas) _lib.render(_viewer, 0) // _surfaceTexture!!.updateTexImage() result.success(true) @@ -402,7 +403,7 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Lo val width = args[0] as Int val height = args[1] as Int val scaleFactor = args[2] as Double - _lib.update_viewport_and_camera_projection(_viewer, width.toUInt(), height.toUInt(), scaleFactor.toFloat()) + // _lib.update_viewport_and_camera_projection(_viewer, width.toUInt(), height.toUInt(), scaleFactor.toFloat()) result.success(true) } "scrollBegin" -> { @@ -758,6 +759,7 @@ class PolyvoxFilamentPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Lo var _ptr:Pointer = Pointer(0) override fun loadResourceFromOwner(path: String?, owner: Pointer?): ResourceBuffer { + Log.i("Loading resource from path $path") var data:ByteArray? = null if(path!!.startsWith("file://")) { data = File(path!!.substring(6)).readBytes()