@babylonjs/react-native 0.4.0-alpha.9 → 0.64.0-alpha.49
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} +7 -15
- 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 -0
- package/ReactNativeEngine.d.ts +7 -0
- package/{ReactNativeEngine.ts → ReactNativeEngine.js} +6 -21
- 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/EngineView.java +120 -28
- 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/BabylonNativeInterop.mm +25 -18
- package/ios/EngineViewManager.mm +32 -12
- package/ios/ReactNativeBabylon.xcodeproj/project.pbxproj +7590 -9882
- 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 +27 -3
- package/shared/XrAnchorHelper.h +229 -0
- package/shared/XrContextHelper.h +179 -0
- package/EngineHook.ts +0 -104
- package/EngineView.tsx +0 -156
- package/NativeCapture.ts +0 -30
- 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) {
|
|
@@ -2,37 +2,41 @@ package com.babylonreactnative;
|
|
|
2
2
|
|
|
3
3
|
import android.annotation.TargetApi;
|
|
4
4
|
import android.graphics.Bitmap;
|
|
5
|
-
import android.graphics.
|
|
5
|
+
import android.graphics.SurfaceTexture;
|
|
6
6
|
import android.os.Build;
|
|
7
7
|
import android.os.Handler;
|
|
8
8
|
import android.os.HandlerThread;
|
|
9
9
|
import android.util.Base64;
|
|
10
10
|
import android.view.MotionEvent;
|
|
11
11
|
import android.view.PixelCopy;
|
|
12
|
+
import android.view.Surface;
|
|
12
13
|
import android.view.SurfaceHolder;
|
|
13
14
|
import android.view.SurfaceView;
|
|
15
|
+
import android.view.TextureView;
|
|
14
16
|
import android.view.View;
|
|
15
17
|
import android.widget.FrameLayout;
|
|
16
18
|
|
|
19
|
+
import androidx.annotation.NonNull;
|
|
20
|
+
|
|
17
21
|
import com.facebook.react.bridge.ReactContext;
|
|
18
22
|
import com.facebook.react.uimanager.UIManagerModule;
|
|
19
23
|
import com.facebook.react.uimanager.events.EventDispatcher;
|
|
20
24
|
|
|
21
25
|
import java.io.ByteArrayOutputStream;
|
|
22
26
|
|
|
23
|
-
public final class EngineView extends FrameLayout implements SurfaceHolder.Callback, View.OnTouchListener {
|
|
27
|
+
public final class EngineView extends FrameLayout implements SurfaceHolder.Callback, TextureView.SurfaceTextureListener, View.OnTouchListener {
|
|
24
28
|
private static final FrameLayout.LayoutParams childViewLayoutParams = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
|
|
25
|
-
private
|
|
26
|
-
private
|
|
29
|
+
private TextureView transparentTextureView;
|
|
30
|
+
private Surface transparentSurface = null;
|
|
31
|
+
private SurfaceView opaqueSurfaceView = null;
|
|
32
|
+
private SurfaceView xrSurfaceView;
|
|
27
33
|
private final EventDispatcher reactEventDispatcher;
|
|
34
|
+
private Runnable renderRunnable;
|
|
28
35
|
|
|
29
36
|
public EngineView(ReactContext reactContext) {
|
|
30
37
|
super(reactContext);
|
|
31
38
|
|
|
32
|
-
this.
|
|
33
|
-
this.primarySurfaceView.setLayoutParams(EngineView.childViewLayoutParams);
|
|
34
|
-
this.primarySurfaceView.getHolder().addCallback(this);
|
|
35
|
-
this.addView(this.primarySurfaceView);
|
|
39
|
+
this.setIsTransparent(false);
|
|
36
40
|
|
|
37
41
|
this.xrSurfaceView = new SurfaceView(reactContext);
|
|
38
42
|
this.xrSurfaceView.setLayoutParams(childViewLayoutParams);
|
|
@@ -57,14 +61,46 @@ public final class EngineView extends FrameLayout implements SurfaceHolder.Callb
|
|
|
57
61
|
|
|
58
62
|
this.setOnTouchListener(this);
|
|
59
63
|
|
|
60
|
-
this.setWillNotDraw(false);
|
|
61
|
-
|
|
62
64
|
this.reactEventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher();
|
|
63
65
|
}
|
|
64
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
|
+
|
|
65
101
|
@Override
|
|
66
102
|
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
|
67
|
-
|
|
103
|
+
this.startRenderLoop();
|
|
68
104
|
}
|
|
69
105
|
|
|
70
106
|
@Override
|
|
@@ -74,24 +110,51 @@ public final class EngineView extends FrameLayout implements SurfaceHolder.Callb
|
|
|
74
110
|
|
|
75
111
|
@Override
|
|
76
112
|
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
|
|
113
|
+
this.removeCallbacks(this.renderRunnable);
|
|
114
|
+
this.renderRunnable = null;
|
|
77
115
|
}
|
|
78
116
|
|
|
79
117
|
@Override
|
|
80
|
-
public
|
|
81
|
-
|
|
82
|
-
|
|
118
|
+
public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surfaceTexture, int i, int i1) {
|
|
119
|
+
this.startRenderLoop();
|
|
120
|
+
this.acquireNewTransparentSurface(surfaceTexture);
|
|
121
|
+
BabylonNativeInterop.updateView(this.transparentSurface);
|
|
83
122
|
}
|
|
84
123
|
|
|
85
124
|
@Override
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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();
|
|
91
147
|
}
|
|
148
|
+
this.transparentSurface = new Surface(surfaceTexture);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// ------------------------------------
|
|
152
|
+
// Common
|
|
92
153
|
|
|
93
|
-
|
|
94
|
-
|
|
154
|
+
@Override
|
|
155
|
+
public boolean onTouch(View view, MotionEvent motionEvent) {
|
|
156
|
+
BabylonNativeInterop.reportMotionEvent(motionEvent);
|
|
157
|
+
return true;
|
|
95
158
|
}
|
|
96
159
|
|
|
97
160
|
@TargetApi(24)
|
|
@@ -113,26 +176,55 @@ public final class EngineView extends FrameLayout implements SurfaceHolder.Callb
|
|
|
113
176
|
helperThread.start();
|
|
114
177
|
final Handler helperThreadHandler = new Handler(helperThread.getLooper());
|
|
115
178
|
|
|
116
|
-
|
|
179
|
+
Surface sourceSurface = this.transparentSurface;
|
|
117
180
|
if (BabylonNativeInterop.isXRActive()) {
|
|
118
|
-
|
|
181
|
+
sourceSurface = this.xrSurfaceView.getHolder().getSurface();
|
|
182
|
+
} else if (this.opaqueSurfaceView != null) {
|
|
183
|
+
sourceSurface = this.opaqueSurfaceView.getHolder().getSurface();
|
|
119
184
|
}
|
|
185
|
+
PixelCopy.request(sourceSurface, bitmap, getOnPixelCopyFinishedListener(bitmap, helperThread), helperThreadHandler);
|
|
186
|
+
}
|
|
120
187
|
|
|
121
|
-
|
|
122
|
-
|
|
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) -> {
|
|
123
193
|
// If the pixel copy was a success then convert the image to a base 64 encoded jpeg and fire the event.
|
|
124
194
|
String encoded = "";
|
|
125
195
|
if (copyResult == PixelCopy.SUCCESS) {
|
|
126
196
|
ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
|
|
127
|
-
bitmap.compress(Bitmap.CompressFormat.JPEG,
|
|
197
|
+
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, byteArrayStream);
|
|
128
198
|
byte[] byteArray = byteArrayStream.toByteArray();
|
|
129
199
|
bitmap.recycle();
|
|
130
200
|
encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
|
|
131
201
|
}
|
|
132
|
-
|
|
133
202
|
SnapshotDataReturnedEvent snapshotEvent = new SnapshotDataReturnedEvent(this.getId(), encoded);
|
|
134
203
|
reactEventDispatcher.dispatchEvent(snapshotEvent);
|
|
135
204
|
helperThread.quitSafely();
|
|
136
|
-
}
|
|
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;
|
|
137
229
|
}
|
|
138
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"}
|
|
@@ -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,65 +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
|
|
|
65
66
|
+ (void)renderView {
|
|
66
|
-
|
|
67
|
+
BabylonNative::RenderView();
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
+ (void)resetView {
|
|
70
|
-
|
|
71
|
+
BabylonNative::ResetView();
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
+ (void)updateXRView:(MTKView*)mtkView {
|
|
74
|
-
|
|
75
|
+
BabylonNative::UpdateXRView(mtkView);
|
|
75
76
|
}
|
|
76
77
|
|
|
77
78
|
+ (bool)isXRActive {
|
|
78
|
-
return
|
|
79
|
+
return BabylonNative::IsXRActive();
|
|
79
80
|
}
|
|
80
81
|
|
|
81
82
|
+ (void)reportTouchEvent:(MTKView*)mtkView touches:(NSSet<UITouch*>*)touches event:(UIEvent*)event {
|
|
82
83
|
for (UITouch* touch in touches) {
|
|
83
84
|
if (touch.view == mtkView) {
|
|
84
|
-
const CGFloat scale =
|
|
85
|
+
const CGFloat scale = mtkView.contentScaleFactor;
|
|
85
86
|
const CGPoint pointerPosition = [touch locationInView:mtkView];
|
|
86
87
|
const uint32_t x = static_cast<uint32_t>(pointerPosition.x * scale);
|
|
87
88
|
const uint32_t y = static_cast<uint32_t>(pointerPosition.y * scale);
|
|
88
89
|
|
|
89
90
|
switch (touch.phase) {
|
|
90
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.
|
|
91
94
|
NSUInteger pointerId = [activeTouches indexOfObject:[NSNull null]];
|
|
92
|
-
if (pointerId
|
|
95
|
+
if (pointerId != NSNotFound) {
|
|
96
|
+
[activeTouches replaceObjectAtIndex:pointerId withObject:touch];
|
|
97
|
+
} else {
|
|
93
98
|
pointerId = [activeTouches count];
|
|
94
99
|
[activeTouches addObject:touch];
|
|
95
|
-
} else {
|
|
96
|
-
[activeTouches replaceObjectAtIndex:pointerId withObject:touch];
|
|
97
100
|
}
|
|
98
|
-
|
|
101
|
+
BabylonNative::SetTouchButtonState(static_cast<uint32_t>(pointerId), true, x, y);
|
|
99
102
|
break;
|
|
100
103
|
}
|
|
101
104
|
|
|
102
105
|
case UITouchPhaseMoved: {
|
|
103
106
|
NSUInteger pointerId = [activeTouches indexOfObject:touch];
|
|
104
|
-
|
|
107
|
+
if (pointerId != NSNotFound) {
|
|
108
|
+
BabylonNative::SetTouchPosition(static_cast<uint32_t>(pointerId), x, y);
|
|
109
|
+
}
|
|
105
110
|
break;
|
|
106
111
|
}
|
|
107
112
|
|
|
108
113
|
case UITouchPhaseEnded:
|
|
109
114
|
case UITouchPhaseCancelled: {
|
|
110
115
|
NSUInteger pointerId = [activeTouches indexOfObject:touch];
|
|
111
|
-
|
|
112
|
-
|
|
116
|
+
if (pointerId != NSNotFound) {
|
|
117
|
+
[activeTouches replaceObjectAtIndex:pointerId withObject:[NSNull null]];
|
|
118
|
+
BabylonNative::SetTouchButtonState(static_cast<uint32_t>(pointerId), false, x, y);
|
|
119
|
+
}
|
|
113
120
|
break;
|
|
114
121
|
}
|
|
115
122
|
|
package/ios/EngineViewManager.mm
CHANGED
|
@@ -11,6 +11,8 @@
|
|
|
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
|
|
|
@@ -22,21 +24,23 @@
|
|
|
22
24
|
- (instancetype)init:(RCTBridge*)_bridge {
|
|
23
25
|
if (self = [super initWithFrame:CGRectZero device:MTLCreateSystemDefaultDevice()]) {
|
|
24
26
|
bridge = _bridge;
|
|
25
|
-
|
|
26
27
|
super.translatesAutoresizingMaskIntoConstraints = false;
|
|
27
28
|
super.colorPixelFormat = MTLPixelFormatBGRA8Unorm_sRGB;
|
|
28
29
|
super.depthStencilPixelFormat = MTLPixelFormatDepth32Float;
|
|
29
|
-
|
|
30
|
-
xrView = [[MTKView alloc] initWithFrame:self.bounds device:self.device];
|
|
31
|
-
xrView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
|
32
|
-
xrView.userInteractionEnabled = false;
|
|
33
|
-
xrView.hidden = true;
|
|
34
|
-
[self addSubview:xrView];
|
|
35
|
-
[BabylonNativeInterop updateXRView:xrView];
|
|
36
30
|
}
|
|
37
31
|
return self;
|
|
38
32
|
}
|
|
39
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
|
+
|
|
40
44
|
- (void)setBounds:(CGRect)bounds {
|
|
41
45
|
[super setBounds:bounds];
|
|
42
46
|
[BabylonNativeInterop updateView:self];
|
|
@@ -60,14 +64,26 @@
|
|
|
60
64
|
|
|
61
65
|
- (void)drawRect:(CGRect)rect {
|
|
62
66
|
if ([BabylonNativeInterop isXRActive]) {
|
|
63
|
-
xrView
|
|
64
|
-
|
|
65
|
-
|
|
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;
|
|
66
78
|
}
|
|
67
79
|
|
|
68
80
|
[BabylonNativeInterop renderView];
|
|
69
81
|
}
|
|
70
82
|
|
|
83
|
+
-(void)dealloc {
|
|
84
|
+
[BabylonNativeInterop updateXRView:nil];
|
|
85
|
+
}
|
|
86
|
+
|
|
71
87
|
- (void)takeSnapshot {
|
|
72
88
|
// We must take the screenshot on the main thread otherwise we might fail to get a valid handle on the view's image.
|
|
73
89
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
@@ -80,7 +96,7 @@
|
|
|
80
96
|
// Grab the image from the graphics context, and convert into a base64 encoded JPG.
|
|
81
97
|
UIImage* capturedImage = UIGraphicsGetImageFromCurrentImageContext();
|
|
82
98
|
UIGraphicsEndImageContext();
|
|
83
|
-
NSData* jpgData = UIImageJPEGRepresentation(capturedImage,
|
|
99
|
+
NSData* jpgData = UIImageJPEGRepresentation(capturedImage, .8f);
|
|
84
100
|
NSString* encodedData = [jpgData base64EncodedStringWithOptions:0];
|
|
85
101
|
|
|
86
102
|
// Fire the onSnapshotDataReturned event if hooked up.
|
|
@@ -98,6 +114,10 @@
|
|
|
98
114
|
|
|
99
115
|
@implementation EngineViewManager
|
|
100
116
|
|
|
117
|
+
RCT_CUSTOM_VIEW_PROPERTY(isTransparent, NSNumber*, EngineView){
|
|
118
|
+
[view setIsTransparentFlag:json];
|
|
119
|
+
}
|
|
120
|
+
|
|
101
121
|
RCT_EXPORT_MODULE(EngineViewManager)
|
|
102
122
|
|
|
103
123
|
RCT_EXPORT_VIEW_PROPERTY(onSnapshotDataReturned, RCTDirectEventBlock)
|