@babylonjs/react-native 0.4.0-alpha.8 → 0.64.0-alpha.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BabylonModule.d.ts +2 -0
- package/{BabylonModule.ts → BabylonModule.js} +9 -12
- package/BabylonModule.js.map +1 -0
- package/EngineHook.d.ts +2 -0
- package/EngineHook.js +178 -0
- package/EngineHook.js.map +1 -0
- package/EngineView.d.ts +13 -0
- package/EngineView.js +94 -0
- package/EngineView.js.map +1 -0
- package/FontFace.d.ts +12 -0
- package/FontFace.js +35 -0
- package/FontFace.js.map +1 -0
- package/NativeCapture.d.ts +14 -0
- package/NativeCapture.js +14 -0
- package/NativeCapture.js.map +1 -0
- package/NativeEngineHook.d.ts +4 -0
- package/NativeEngineHook.js +43 -0
- package/NativeEngineHook.js.map +1 -0
- package/NativeEngineView.d.ts +10 -0
- package/NativeEngineView.js +3 -0
- package/NativeEngineView.js.map +1 -0
- package/README.md +8 -8
- package/ReactNativeEngine.d.ts +7 -0
- package/ReactNativeEngine.js +33 -0
- package/ReactNativeEngine.js.map +1 -0
- package/VersionValidation.d.ts +1 -0
- package/{VersionValidation.ts → VersionValidation.js} +3 -3
- package/VersionValidation.js.map +1 -0
- package/android/build.gradle +13 -1
- package/android/include/IXrContextARCore.h +10 -0
- package/android/src/main/java/com/babylonreactnative/BabylonModule.java +6 -4
- package/android/src/main/java/com/babylonreactnative/BabylonNativeInterop.java +20 -6
- package/android/src/main/java/com/babylonreactnative/EngineView.java +151 -8
- package/android/src/main/java/com/babylonreactnative/EngineViewManager.java +8 -0
- package/android/src/main/jniLibs/arm64-v8a/libBabylonNative.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libturbomodulejsijni.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libBabylonNative.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libturbomodulejsijni.so +0 -0
- package/android/src/main/jniLibs/x86/libBabylonNative.so +0 -0
- package/android/src/main/jniLibs/x86/libturbomodulejsijni.so +0 -0
- package/{index.ts → index.d.ts} +1 -0
- package/index.js +5 -0
- package/index.js.map +1 -0
- package/ios/BabylonModule.mm +7 -0
- package/ios/BabylonNativeInterop.h +4 -0
- package/ios/BabylonNativeInterop.mm +37 -14
- package/ios/EngineViewManager.mm +41 -3
- package/ios/ReactNativeBabylon.xcodeproj/project.pbxproj +7532 -9825
- package/ios/include/IXrContextARKit.h +10 -0
- package/ios/libs/libBabylonNative.a +0 -0
- package/ios/libs/libCanvas.a +0 -0
- package/ios/libs/libGenericCodeGen.a +0 -0
- package/ios/libs/libGraphics.a +0 -0
- package/ios/libs/libJsRuntime.a +0 -0
- package/ios/libs/libMachineIndependent.a +0 -0
- package/ios/libs/libNativeCapture.a +0 -0
- package/ios/libs/libNativeEngine.a +0 -0
- package/ios/libs/libNativeInput.a +0 -0
- package/ios/libs/libNativeOptimizations.a +0 -0
- package/ios/libs/libNativeTracing.a +0 -0
- package/ios/libs/libNativeXr.a +0 -0
- package/ios/libs/libOGLCompiler.a +0 -0
- package/ios/libs/libOSDependent.a +0 -0
- package/ios/libs/libSPIRV.a +0 -0
- package/ios/libs/libUrlLib.a +0 -0
- package/ios/libs/libWindow.a +0 -0
- package/ios/libs/libXMLHttpRequest.a +0 -0
- package/ios/libs/libastc-codec.a +0 -0
- package/ios/libs/libastc.a +0 -0
- package/ios/libs/libbgfx.a +0 -0
- package/ios/libs/libbimg.a +0 -0
- package/ios/libs/libbx.a +0 -0
- package/ios/libs/libglslang.a +0 -0
- package/ios/libs/libnapi.a +0 -0
- package/ios/libs/libspirv-cross-core.a +0 -0
- package/ios/libs/libspirv-cross-glsl.a +0 -0
- package/ios/libs/libspirv-cross-msl.a +0 -0
- package/ios/libs/libtinyexr.a +0 -0
- package/ios/libs/libxr.a +0 -0
- package/package.json +53 -52
- package/shared/BabylonNative.h +30 -3
- package/shared/XrAnchorHelper.h +229 -0
- package/shared/XrContextHelper.h +179 -0
- package/EngineHook.ts +0 -103
- package/EngineView.tsx +0 -156
- package/NativeCapture.ts +0 -30
- package/ReactNativeEngine.ts +0 -69
- package/ios/libs/libspirv-cross-hlsl.a +0 -0
package/android/build.gradle
CHANGED
|
@@ -19,6 +19,10 @@ def safeExtGet(prop, fallback) {
|
|
|
19
19
|
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
def reactProperties = new Properties()
|
|
23
|
+
file("$projectDir/../../../react-native/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) }
|
|
24
|
+
def REACT_VERSION = reactProperties.getProperty("VERSION_NAME").split("\\.")[1].toInteger()
|
|
25
|
+
|
|
22
26
|
apply plugin: 'com.android.library'
|
|
23
27
|
apply plugin: 'maven'
|
|
24
28
|
|
|
@@ -59,6 +63,14 @@ android {
|
|
|
59
63
|
}
|
|
60
64
|
}
|
|
61
65
|
|
|
66
|
+
// The full/real version of libturbomodulejsijni.so will be built and included in apps using React Native 0.64 or newer,
|
|
67
|
+
// so exclude Babylon React Native's minimal version of these libs in this case.
|
|
68
|
+
if (REACT_VERSION >= 64) {
|
|
69
|
+
android.packagingOptions.excludes += 'lib/armeabi-v7a/libturbomodulejsijni.so'
|
|
70
|
+
android.packagingOptions.excludes += 'lib/arm64-v8a/libturbomodulejsijni.so'
|
|
71
|
+
android.packagingOptions.excludes += 'lib/x86/libturbomodulejsijni.so'
|
|
72
|
+
}
|
|
73
|
+
|
|
62
74
|
repositories {
|
|
63
75
|
// ref: https://www.baeldung.com/maven-local-repository
|
|
64
76
|
mavenLocal()
|
|
@@ -77,7 +89,7 @@ repositories {
|
|
|
77
89
|
dependencies {
|
|
78
90
|
//noinspection GradleDynamicVersion
|
|
79
91
|
implementation 'com.facebook.react:react-native:+' // From node_modules
|
|
80
|
-
implementation 'com.google.ar:core:1.
|
|
92
|
+
implementation 'com.google.ar:core:1.22.0'
|
|
81
93
|
}
|
|
82
94
|
|
|
83
95
|
def configureReactNativePom(def pom) {
|
|
@@ -27,9 +27,11 @@ public final class BabylonModule extends ReactContextBaseJavaModule {
|
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
@ReactMethod
|
|
31
|
+
public void resetView(Promise promise) {
|
|
32
|
+
this.getReactApplicationContext().runOnUiQueueThread(() -> {
|
|
33
|
+
BabylonNativeInterop.resetView();
|
|
34
|
+
promise.resolve(null);
|
|
35
|
+
});
|
|
34
36
|
}
|
|
35
37
|
}
|
|
@@ -19,11 +19,14 @@ public final class BabylonNativeInterop {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
public static native void initialize(Context context, long jsiRuntimeRef, CallInvokerHolder jsCallInvokerHolder);
|
|
22
|
-
public static native void deinitialize();
|
|
23
22
|
public static native void setCurrentActivity(Activity activity);
|
|
24
23
|
public static native void pause();
|
|
25
24
|
public static native void resume();
|
|
26
25
|
public static native void updateView(Surface surface);
|
|
26
|
+
public static native void renderView();
|
|
27
|
+
public static native void resetView();
|
|
28
|
+
public static native void updateXRView(Surface surface);
|
|
29
|
+
public static native boolean isXRActive();
|
|
27
30
|
public static native void setTouchButtonState(int pointerId, boolean isDown, int x, int y);
|
|
28
31
|
public static native void setTouchPosition(int pointerId, int x, int y);
|
|
29
32
|
}
|
|
@@ -54,7 +57,6 @@ public final class BabylonNativeInterop {
|
|
|
54
57
|
|
|
55
58
|
@Override
|
|
56
59
|
public void onHostDestroy() {
|
|
57
|
-
BabylonNative.deinitialize();
|
|
58
60
|
}
|
|
59
61
|
};
|
|
60
62
|
|
|
@@ -79,14 +81,26 @@ public final class BabylonNativeInterop {
|
|
|
79
81
|
reactContext.addActivityEventListener(BabylonNativeInterop.activityEventListener);
|
|
80
82
|
}
|
|
81
83
|
|
|
82
|
-
public static void deinitialize() {
|
|
83
|
-
BabylonNative.deinitialize();
|
|
84
|
-
}
|
|
85
|
-
|
|
86
84
|
public static void updateView(Surface surface) {
|
|
87
85
|
BabylonNative.updateView(surface);
|
|
88
86
|
}
|
|
89
87
|
|
|
88
|
+
public static void renderView() {
|
|
89
|
+
BabylonNative.renderView();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
public static void resetView() {
|
|
93
|
+
BabylonNative.resetView();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
public static void updateXRView(Surface surface) {
|
|
97
|
+
BabylonNative.updateXRView(surface);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public static boolean isXRActive() {
|
|
101
|
+
return BabylonNative.isXRActive();
|
|
102
|
+
}
|
|
103
|
+
|
|
90
104
|
public static void reportMotionEvent(MotionEvent motionEvent) {
|
|
91
105
|
int maskedAction = motionEvent.getActionMasked();
|
|
92
106
|
boolean isPointerDown = maskedAction == MotionEvent.ACTION_DOWN || maskedAction == MotionEvent.ACTION_POINTER_DOWN;
|
|
@@ -2,15 +2,21 @@ package com.babylonreactnative;
|
|
|
2
2
|
|
|
3
3
|
import android.annotation.TargetApi;
|
|
4
4
|
import android.graphics.Bitmap;
|
|
5
|
+
import android.graphics.SurfaceTexture;
|
|
5
6
|
import android.os.Build;
|
|
6
7
|
import android.os.Handler;
|
|
7
8
|
import android.os.HandlerThread;
|
|
8
9
|
import android.util.Base64;
|
|
9
10
|
import android.view.MotionEvent;
|
|
10
11
|
import android.view.PixelCopy;
|
|
12
|
+
import android.view.Surface;
|
|
11
13
|
import android.view.SurfaceHolder;
|
|
12
14
|
import android.view.SurfaceView;
|
|
15
|
+
import android.view.TextureView;
|
|
13
16
|
import android.view.View;
|
|
17
|
+
import android.widget.FrameLayout;
|
|
18
|
+
|
|
19
|
+
import androidx.annotation.NonNull;
|
|
14
20
|
|
|
15
21
|
import com.facebook.react.bridge.ReactContext;
|
|
16
22
|
import com.facebook.react.uimanager.UIManagerModule;
|
|
@@ -18,19 +24,83 @@ import com.facebook.react.uimanager.events.EventDispatcher;
|
|
|
18
24
|
|
|
19
25
|
import java.io.ByteArrayOutputStream;
|
|
20
26
|
|
|
21
|
-
public final class EngineView extends
|
|
27
|
+
public final class EngineView extends FrameLayout implements SurfaceHolder.Callback, TextureView.SurfaceTextureListener, View.OnTouchListener {
|
|
28
|
+
private static final FrameLayout.LayoutParams childViewLayoutParams = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
|
|
29
|
+
private TextureView transparentTextureView;
|
|
30
|
+
private Surface transparentSurface = null;
|
|
31
|
+
private SurfaceView opaqueSurfaceView = null;
|
|
32
|
+
private SurfaceView xrSurfaceView;
|
|
22
33
|
private final EventDispatcher reactEventDispatcher;
|
|
34
|
+
private Runnable renderRunnable;
|
|
23
35
|
|
|
24
36
|
public EngineView(ReactContext reactContext) {
|
|
25
37
|
super(reactContext);
|
|
26
|
-
|
|
38
|
+
|
|
39
|
+
this.setIsTransparent(false);
|
|
40
|
+
|
|
41
|
+
this.xrSurfaceView = new SurfaceView(reactContext);
|
|
42
|
+
this.xrSurfaceView.setLayoutParams(childViewLayoutParams);
|
|
43
|
+
this.xrSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
|
|
44
|
+
@Override
|
|
45
|
+
public void surfaceCreated(SurfaceHolder holder) {
|
|
46
|
+
// surfaceChanged is also called when the surface is created, so just do all the handling there
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@Override
|
|
50
|
+
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
|
51
|
+
BabylonNativeInterop.updateXRView(holder.getSurface());
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@Override
|
|
55
|
+
public void surfaceDestroyed(SurfaceHolder holder) {
|
|
56
|
+
BabylonNativeInterop.updateXRView(null);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
this.xrSurfaceView.setVisibility(View.INVISIBLE);
|
|
60
|
+
this.addView(this.xrSurfaceView);
|
|
61
|
+
|
|
27
62
|
this.setOnTouchListener(this);
|
|
63
|
+
|
|
28
64
|
this.reactEventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher();
|
|
29
65
|
}
|
|
30
66
|
|
|
67
|
+
// ------------------------------------
|
|
68
|
+
// TextureView related
|
|
69
|
+
|
|
70
|
+
public void setIsTransparent(Boolean isTransparent) {
|
|
71
|
+
if (isTransparent) {
|
|
72
|
+
if (this.opaqueSurfaceView != null) {
|
|
73
|
+
this.opaqueSurfaceView.setVisibility(View.GONE);
|
|
74
|
+
this.opaqueSurfaceView = null;
|
|
75
|
+
}
|
|
76
|
+
if (this.transparentTextureView == null) {
|
|
77
|
+
this.transparentTextureView = new TextureView(this.getContext());
|
|
78
|
+
this.transparentTextureView.setLayoutParams(EngineView.childViewLayoutParams);
|
|
79
|
+
this.transparentTextureView.setSurfaceTextureListener(this);
|
|
80
|
+
this.transparentTextureView.setOpaque(false);
|
|
81
|
+
this.addView(this.transparentTextureView);
|
|
82
|
+
}
|
|
83
|
+
} else {
|
|
84
|
+
if (this.transparentTextureView != null) {
|
|
85
|
+
this.transparentTextureView.setVisibility(View.GONE);
|
|
86
|
+
this.transparentTextureView = null;
|
|
87
|
+
}
|
|
88
|
+
if (this.opaqueSurfaceView == null) {
|
|
89
|
+
this.opaqueSurfaceView = new SurfaceView(this.getContext());
|
|
90
|
+
this.opaqueSurfaceView.setLayoutParams(EngineView.childViewLayoutParams);
|
|
91
|
+
this.opaqueSurfaceView.getHolder().addCallback(this);
|
|
92
|
+
this.addView(this.opaqueSurfaceView);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// xr view needs to be on top of views that might be created after it.
|
|
96
|
+
if (this.xrSurfaceView != null) {
|
|
97
|
+
this.xrSurfaceView.bringToFront();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
31
101
|
@Override
|
|
32
102
|
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
|
33
|
-
|
|
103
|
+
this.startRenderLoop();
|
|
34
104
|
}
|
|
35
105
|
|
|
36
106
|
@Override
|
|
@@ -40,8 +110,47 @@ public final class EngineView extends SurfaceView implements SurfaceHolder.Callb
|
|
|
40
110
|
|
|
41
111
|
@Override
|
|
42
112
|
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
|
|
113
|
+
this.removeCallbacks(this.renderRunnable);
|
|
114
|
+
this.renderRunnable = null;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
@Override
|
|
118
|
+
public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surfaceTexture, int i, int i1) {
|
|
119
|
+
this.startRenderLoop();
|
|
120
|
+
this.acquireNewTransparentSurface(surfaceTexture);
|
|
121
|
+
BabylonNativeInterop.updateView(this.transparentSurface);
|
|
43
122
|
}
|
|
44
123
|
|
|
124
|
+
@Override
|
|
125
|
+
public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surfaceTexture, int i, int i1) {
|
|
126
|
+
this.acquireNewTransparentSurface(surfaceTexture);
|
|
127
|
+
BabylonNativeInterop.updateView(this.transparentSurface);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
@Override
|
|
131
|
+
public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surfaceTexture) {
|
|
132
|
+
this.stopRenderLoop();
|
|
133
|
+
this.transparentSurface.release();
|
|
134
|
+
this.transparentSurface = null;
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
@Override
|
|
139
|
+
public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surfaceTexture) {
|
|
140
|
+
this.acquireNewTransparentSurface(surfaceTexture);
|
|
141
|
+
BabylonNativeInterop.updateView(this.transparentSurface);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private void acquireNewTransparentSurface(@NonNull SurfaceTexture surfaceTexture) {
|
|
145
|
+
if (this.transparentSurface != null) {
|
|
146
|
+
this.transparentSurface.release();
|
|
147
|
+
}
|
|
148
|
+
this.transparentSurface = new Surface(surfaceTexture);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// ------------------------------------
|
|
152
|
+
// Common
|
|
153
|
+
|
|
45
154
|
@Override
|
|
46
155
|
public boolean onTouch(View view, MotionEvent motionEvent) {
|
|
47
156
|
BabylonNativeInterop.reportMotionEvent(motionEvent);
|
|
@@ -67,21 +176,55 @@ public final class EngineView extends SurfaceView implements SurfaceHolder.Callb
|
|
|
67
176
|
helperThread.start();
|
|
68
177
|
final Handler helperThreadHandler = new Handler(helperThread.getLooper());
|
|
69
178
|
|
|
70
|
-
|
|
71
|
-
|
|
179
|
+
Surface sourceSurface = this.transparentSurface;
|
|
180
|
+
if (BabylonNativeInterop.isXRActive()) {
|
|
181
|
+
sourceSurface = this.xrSurfaceView.getHolder().getSurface();
|
|
182
|
+
} else if (this.opaqueSurfaceView != null) {
|
|
183
|
+
sourceSurface = this.opaqueSurfaceView.getHolder().getSurface();
|
|
184
|
+
}
|
|
185
|
+
PixelCopy.request(sourceSurface, bitmap, getOnPixelCopyFinishedListener(bitmap, helperThread), helperThreadHandler);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// ---------------------------------------------------------------------------------------------
|
|
189
|
+
// Returns the listener for the PixelCopy.request function call
|
|
190
|
+
@NonNull
|
|
191
|
+
private PixelCopy.OnPixelCopyFinishedListener getOnPixelCopyFinishedListener(Bitmap bitmap, HandlerThread helperThread) {
|
|
192
|
+
return (copyResult) -> {
|
|
72
193
|
// If the pixel copy was a success then convert the image to a base 64 encoded jpeg and fire the event.
|
|
73
194
|
String encoded = "";
|
|
74
195
|
if (copyResult == PixelCopy.SUCCESS) {
|
|
75
196
|
ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
|
|
76
|
-
bitmap.compress(Bitmap.CompressFormat.JPEG,
|
|
197
|
+
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, byteArrayStream);
|
|
77
198
|
byte[] byteArray = byteArrayStream.toByteArray();
|
|
78
199
|
bitmap.recycle();
|
|
79
200
|
encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
|
|
80
201
|
}
|
|
81
|
-
|
|
82
202
|
SnapshotDataReturnedEvent snapshotEvent = new SnapshotDataReturnedEvent(this.getId(), encoded);
|
|
83
203
|
reactEventDispatcher.dispatchEvent(snapshotEvent);
|
|
84
204
|
helperThread.quitSafely();
|
|
85
|
-
}
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
private void startRenderLoop() {
|
|
209
|
+
if(this.renderRunnable == null){
|
|
210
|
+
this.renderRunnable = new Runnable() {
|
|
211
|
+
@Override
|
|
212
|
+
public void run() {
|
|
213
|
+
if (BabylonNativeInterop.isXRActive()) {
|
|
214
|
+
EngineView.this.xrSurfaceView.setVisibility(View.VISIBLE);
|
|
215
|
+
} else {
|
|
216
|
+
EngineView.this.xrSurfaceView.setVisibility(View.INVISIBLE);
|
|
217
|
+
}
|
|
218
|
+
BabylonNativeInterop.renderView();
|
|
219
|
+
EngineView.this.postOnAnimation(this);
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
this.postOnAnimation(this.renderRunnable);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
private void stopRenderLoop() {
|
|
227
|
+
this.removeCallbacks(this.renderRunnable);
|
|
228
|
+
this.renderRunnable = null;
|
|
86
229
|
}
|
|
87
230
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
package com.babylonreactnative;
|
|
2
2
|
|
|
3
|
+
import android.widget.FrameLayout;
|
|
4
|
+
|
|
3
5
|
import androidx.annotation.NonNull;
|
|
4
6
|
import androidx.annotation.Nullable;
|
|
5
7
|
|
|
@@ -7,6 +9,7 @@ import com.facebook.react.bridge.ReadableArray;
|
|
|
7
9
|
import com.facebook.react.common.MapBuilder;
|
|
8
10
|
import com.facebook.react.uimanager.SimpleViewManager;
|
|
9
11
|
import com.facebook.react.uimanager.ThemedReactContext;
|
|
12
|
+
import com.facebook.react.uimanager.annotations.ReactProp;
|
|
10
13
|
|
|
11
14
|
import java.util.Map;
|
|
12
15
|
|
|
@@ -20,6 +23,11 @@ public final class EngineViewManager extends SimpleViewManager<EngineView> {
|
|
|
20
23
|
return "EngineView";
|
|
21
24
|
}
|
|
22
25
|
|
|
26
|
+
@ReactProp(name = "isTransparent")
|
|
27
|
+
public void setIsTransparent(EngineView view, Boolean isTransparent) {
|
|
28
|
+
view.setIsTransparent(isTransparent);
|
|
29
|
+
}
|
|
30
|
+
|
|
23
31
|
@NonNull
|
|
24
32
|
@Override
|
|
25
33
|
protected EngineView createViewInstance(@NonNull ThemedReactContext reactContext) {
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/{index.ts → index.d.ts}
RENAMED
package/index.js
ADDED
package/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../Modules/@babylonjs/react-native/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC"}
|
package/ios/BabylonModule.mm
CHANGED
|
@@ -25,4 +25,11 @@ RCT_EXPORT_METHOD(initialize:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseR
|
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
RCT_EXPORT_METHOD(resetView:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
|
|
29
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
30
|
+
[BabylonNativeInterop resetView];
|
|
31
|
+
resolve([NSNull null]);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
28
35
|
@end
|
|
@@ -6,5 +6,9 @@
|
|
|
6
6
|
@interface BabylonNativeInterop : NSObject
|
|
7
7
|
+ (void)initialize:(RCTBridge*)bridge;
|
|
8
8
|
+ (void)updateView:(MTKView*)mtkView;
|
|
9
|
+
+ (void)renderView;
|
|
10
|
+
+ (void)resetView;
|
|
11
|
+
+ (void)updateXRView:(MTKView*)mtkView;
|
|
12
|
+
+ (bool)isXRActive;
|
|
9
13
|
+ (void)reportTouchEvent:(MTKView*)mtkView touches:(NSSet<UITouch*>*)touches event:(UIEvent*)event;
|
|
10
14
|
@end
|
|
@@ -24,7 +24,7 @@ namespace {
|
|
|
24
24
|
|
|
25
25
|
@implementation BabylonNativeInterop
|
|
26
26
|
|
|
27
|
-
static NSMutableArray* activeTouches;
|
|
27
|
+
static NSMutableArray* activeTouches = [NSMutableArray new];
|
|
28
28
|
|
|
29
29
|
+ (void)initialize:(RCTBridge*)bridge {
|
|
30
30
|
auto jsCallInvoker{ bridge.jsCallInvoker };
|
|
@@ -36,7 +36,7 @@ static NSMutableArray* activeTouches;
|
|
|
36
36
|
});
|
|
37
37
|
} };
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
BabylonNative::Initialize(*GetJSIRuntime(bridge), std::move(jsDispatcher));
|
|
40
40
|
|
|
41
41
|
[[NSNotificationCenter defaultCenter] removeObserver:self
|
|
42
42
|
name:RCTBridgeWillInvalidateModulesNotification
|
|
@@ -51,49 +51,72 @@ static NSMutableArray* activeTouches;
|
|
|
51
51
|
// NOTE: This happens during dev mode reload, when the JS engine is being shutdown and restarted.
|
|
52
52
|
+ (void)onBridgeWillInvalidate:(NSNotification*)notification
|
|
53
53
|
{
|
|
54
|
-
|
|
54
|
+
BabylonNative::Deinitialize();
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
+ (void)updateView:(MTKView*)mtkView {
|
|
58
|
-
const
|
|
59
|
-
const int
|
|
58
|
+
const CGFloat scale = mtkView.contentScaleFactor;
|
|
59
|
+
const int width = static_cast<int>(mtkView.bounds.size.width * scale);
|
|
60
|
+
const int height = static_cast<int>(mtkView.bounds.size.height * scale);
|
|
60
61
|
if (width != 0 && height != 0) {
|
|
61
|
-
|
|
62
|
+
BabylonNative::UpdateView(mtkView, width, height);
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
65
|
|
|
66
|
+
+ (void)renderView {
|
|
67
|
+
BabylonNative::RenderView();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
+ (void)resetView {
|
|
71
|
+
BabylonNative::ResetView();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
+ (void)updateXRView:(MTKView*)mtkView {
|
|
75
|
+
BabylonNative::UpdateXRView(mtkView);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
+ (bool)isXRActive {
|
|
79
|
+
return BabylonNative::IsXRActive();
|
|
80
|
+
}
|
|
81
|
+
|
|
65
82
|
+ (void)reportTouchEvent:(MTKView*)mtkView touches:(NSSet<UITouch*>*)touches event:(UIEvent*)event {
|
|
66
83
|
for (UITouch* touch in touches) {
|
|
67
84
|
if (touch.view == mtkView) {
|
|
68
|
-
const CGFloat scale =
|
|
85
|
+
const CGFloat scale = mtkView.contentScaleFactor;
|
|
69
86
|
const CGPoint pointerPosition = [touch locationInView:mtkView];
|
|
70
87
|
const uint32_t x = static_cast<uint32_t>(pointerPosition.x * scale);
|
|
71
88
|
const uint32_t y = static_cast<uint32_t>(pointerPosition.y * scale);
|
|
72
89
|
|
|
73
90
|
switch (touch.phase) {
|
|
74
91
|
case UITouchPhaseBegan: {
|
|
92
|
+
// The activeTouches array only grows, it does not shrink (to keep indices constant since they are used as pointer ids),
|
|
93
|
+
// so look for an unused (null) array element and reuse it if found. Otherwise, add a new entry to the array.
|
|
75
94
|
NSUInteger pointerId = [activeTouches indexOfObject:[NSNull null]];
|
|
76
|
-
if (pointerId
|
|
95
|
+
if (pointerId != NSNotFound) {
|
|
96
|
+
[activeTouches replaceObjectAtIndex:pointerId withObject:touch];
|
|
97
|
+
} else {
|
|
77
98
|
pointerId = [activeTouches count];
|
|
78
99
|
[activeTouches addObject:touch];
|
|
79
|
-
} else {
|
|
80
|
-
[activeTouches replaceObjectAtIndex:pointerId withObject:touch];
|
|
81
100
|
}
|
|
82
|
-
|
|
101
|
+
BabylonNative::SetTouchButtonState(static_cast<uint32_t>(pointerId), true, x, y);
|
|
83
102
|
break;
|
|
84
103
|
}
|
|
85
104
|
|
|
86
105
|
case UITouchPhaseMoved: {
|
|
87
106
|
NSUInteger pointerId = [activeTouches indexOfObject:touch];
|
|
88
|
-
|
|
107
|
+
if (pointerId != NSNotFound) {
|
|
108
|
+
BabylonNative::SetTouchPosition(static_cast<uint32_t>(pointerId), x, y);
|
|
109
|
+
}
|
|
89
110
|
break;
|
|
90
111
|
}
|
|
91
112
|
|
|
92
113
|
case UITouchPhaseEnded:
|
|
93
114
|
case UITouchPhaseCancelled: {
|
|
94
115
|
NSUInteger pointerId = [activeTouches indexOfObject:touch];
|
|
95
|
-
|
|
96
|
-
|
|
116
|
+
if (pointerId != NSNotFound) {
|
|
117
|
+
[activeTouches replaceObjectAtIndex:pointerId withObject:[NSNull null]];
|
|
118
|
+
BabylonNative::SetTouchButtonState(static_cast<uint32_t>(pointerId), false, x, y);
|
|
119
|
+
}
|
|
97
120
|
break;
|
|
98
121
|
}
|
|
99
122
|
|
package/ios/EngineViewManager.mm
CHANGED
|
@@ -11,17 +11,19 @@
|
|
|
11
11
|
@interface EngineView : MTKView
|
|
12
12
|
|
|
13
13
|
@property (nonatomic, copy) RCTDirectEventBlock onSnapshotDataReturned;
|
|
14
|
+
@property (nonatomic, assign) BOOL isTransparent;
|
|
15
|
+
|
|
14
16
|
|
|
15
17
|
@end
|
|
16
18
|
|
|
17
19
|
@implementation EngineView {
|
|
18
|
-
RCTBridge* bridge;
|
|
20
|
+
const RCTBridge* bridge;
|
|
21
|
+
MTKView* xrView;
|
|
19
22
|
}
|
|
20
23
|
|
|
21
24
|
- (instancetype)init:(RCTBridge*)_bridge {
|
|
22
25
|
if (self = [super initWithFrame:CGRectZero device:MTLCreateSystemDefaultDevice()]) {
|
|
23
26
|
bridge = _bridge;
|
|
24
|
-
|
|
25
27
|
super.translatesAutoresizingMaskIntoConstraints = false;
|
|
26
28
|
super.colorPixelFormat = MTLPixelFormatBGRA8Unorm_sRGB;
|
|
27
29
|
super.depthStencilPixelFormat = MTLPixelFormatDepth32Float;
|
|
@@ -29,6 +31,16 @@
|
|
|
29
31
|
return self;
|
|
30
32
|
}
|
|
31
33
|
|
|
34
|
+
- (void)setIsTransparentFlag:(NSNumber*)isTransparentFlag {
|
|
35
|
+
BOOL isTransparent = [isTransparentFlag intValue] == 1;
|
|
36
|
+
if(isTransparent){
|
|
37
|
+
[self setOpaque:NO];
|
|
38
|
+
} else {
|
|
39
|
+
[self setOpaque:YES];
|
|
40
|
+
}
|
|
41
|
+
self.isTransparent = isTransparent;
|
|
42
|
+
}
|
|
43
|
+
|
|
32
44
|
- (void)setBounds:(CGRect)bounds {
|
|
33
45
|
[super setBounds:bounds];
|
|
34
46
|
[BabylonNativeInterop updateView:self];
|
|
@@ -50,6 +62,28 @@
|
|
|
50
62
|
[BabylonNativeInterop reportTouchEvent:self touches:touches event:event];
|
|
51
63
|
}
|
|
52
64
|
|
|
65
|
+
- (void)drawRect:(CGRect)rect {
|
|
66
|
+
if ([BabylonNativeInterop isXRActive]) {
|
|
67
|
+
if (!xrView) {
|
|
68
|
+
xrView = [[MTKView alloc] initWithFrame:self.bounds device:self.device];
|
|
69
|
+
xrView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
|
70
|
+
xrView.userInteractionEnabled = false;
|
|
71
|
+
[self addSubview:xrView];
|
|
72
|
+
[BabylonNativeInterop updateXRView:xrView];
|
|
73
|
+
}
|
|
74
|
+
} else if (xrView) {
|
|
75
|
+
[BabylonNativeInterop updateXRView:nil];
|
|
76
|
+
[xrView removeFromSuperview];
|
|
77
|
+
xrView = nil;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
[BabylonNativeInterop renderView];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
-(void)dealloc {
|
|
84
|
+
[BabylonNativeInterop updateXRView:nil];
|
|
85
|
+
}
|
|
86
|
+
|
|
53
87
|
- (void)takeSnapshot {
|
|
54
88
|
// We must take the screenshot on the main thread otherwise we might fail to get a valid handle on the view's image.
|
|
55
89
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
@@ -62,7 +96,7 @@
|
|
|
62
96
|
// Grab the image from the graphics context, and convert into a base64 encoded JPG.
|
|
63
97
|
UIImage* capturedImage = UIGraphicsGetImageFromCurrentImageContext();
|
|
64
98
|
UIGraphicsEndImageContext();
|
|
65
|
-
NSData* jpgData = UIImageJPEGRepresentation(capturedImage,
|
|
99
|
+
NSData* jpgData = UIImageJPEGRepresentation(capturedImage, .8f);
|
|
66
100
|
NSString* encodedData = [jpgData base64EncodedStringWithOptions:0];
|
|
67
101
|
|
|
68
102
|
// Fire the onSnapshotDataReturned event if hooked up.
|
|
@@ -80,6 +114,10 @@
|
|
|
80
114
|
|
|
81
115
|
@implementation EngineViewManager
|
|
82
116
|
|
|
117
|
+
RCT_CUSTOM_VIEW_PROPERTY(isTransparent, NSNumber*, EngineView){
|
|
118
|
+
[view setIsTransparentFlag:json];
|
|
119
|
+
}
|
|
120
|
+
|
|
83
121
|
RCT_EXPORT_MODULE(EngineViewManager)
|
|
84
122
|
|
|
85
123
|
RCT_EXPORT_VIEW_PROPERTY(onSnapshotDataReturned, RCTDirectEventBlock)
|