Skip to content

Commit a16f403

Browse files
committed
[Example] Add custom native ARSCNView example (With ARFaceTrackingConfiguration
1 parent 659e977 commit a16f403

File tree

9 files changed

+119
-23
lines changed

9 files changed

+119
-23
lines changed

packages/RNWebRTCARExample/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Example for react-native-webrtc-ar-session
22

3+
- Example 1: AR scene example with `react-native-arkit`
4+
- Example 2: AR face tracking example with [custom native view](ios/ExampleARSCNViewManager.m) (You can switch it on Setting)
5+
36
## Installation
47

58
```bash
Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
1-
//
2-
// ExampleARSCNViewManager.h
3-
// RNWebRTCARExample
4-
//
5-
// Created by Jhen-Jie Hong on 2020/2/27.
6-
// Copyright © 2020 Facebook. All rights reserved.
7-
//
1+
#import <ARkit/ARKit.h>
2+
#import <React/RCTViewManager.h>
3+
#import <React/RCTBridgeModule.h>
84

9-
#ifndef ExampleARSCNViewManager_h
10-
#define ExampleARSCNViewManager_h
5+
@interface ExampleARSCNViewManager : RCTViewManager <RCTBridgeModule>
116

12-
13-
#endif /* ExampleARSCNViewManager_h */
7+
@end
Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,60 @@
1-
//
2-
// ExampleARSCNViewManager.m
3-
// RNWebRTCARExample
4-
//
5-
// Created by Jhen-Jie Hong on 2020/2/27.
6-
// Copyright © 2020 Facebook. All rights reserved.
7-
//
8-
9-
#import <Foundation/Foundation.h>
1+
#import "ExampleARSCNViewManager.h"
2+
#import <React/RCTUIManager.h>
3+
#import <RNWebRTCARSession/RNWebRTCARSession.h>
4+
5+
@interface ExampleARSCNViewManager () <ARSCNViewDelegate, ARSessionDelegate>
6+
7+
@end
8+
9+
@implementation ExampleARSCNViewManager
10+
11+
static ARSCNView *_arView = nil;
12+
13+
RCT_EXPORT_MODULE()
14+
15+
- (UIView *)view
16+
{
17+
return [self instance];
18+
}
19+
20+
- (ARSCNView*)instance {
21+
if (_arView != nil) {
22+
return _arView;
23+
}
24+
ARSCNView *arView = [[ARSCNView alloc] init];
25+
arView.delegate = self;
26+
arView.session.delegate = self;
27+
arView.showsStatistics = true;
28+
_arView = arView;
29+
[self resume];
30+
return _arView;
31+
}
32+
33+
- (void)pause {
34+
[_arView.session pause];
35+
}
36+
37+
- (void)resume {
38+
ARFaceTrackingConfiguration *configuration = [ARFaceTrackingConfiguration new];
39+
[_arView.session runWithConfiguration:configuration];
40+
}
41+
42+
#pragma mark - ARSCNViewDelegate
43+
- (nullable SCNNode *)renderer:(id <SCNSceneRenderer>)renderer nodeForAnchor:(ARAnchor *)anchor {
44+
ARSCNFaceGeometry *faceMesh = [ARSCNFaceGeometry faceGeometryWithDevice:_arView.device];
45+
SCNNode *node = [SCNNode nodeWithGeometry:faceMesh];
46+
node.geometry.firstMaterial.fillMode = SCNFillModeLines;
47+
return node;
48+
}
49+
50+
RCT_EXPORT_METHOD(injectARSession:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
51+
[RNWebRTCARSession setArView:_arView];
52+
resolve(@{});
53+
}
54+
55+
RCT_EXPORT_METHOD(revertARSession:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
56+
[RNWebRTCARSession setArView:nil];
57+
resolve(@{});
58+
}
59+
60+
@end

packages/RNWebRTCARExample/ios/RNWebRTCARExample.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
2DCD954D1E0B4F2C00145EB5 /* RNWebRTCARExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* RNWebRTCARExampleTests.m */; };
1919
7F53579623FCD62A00634B31 /* PocketSVG.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F53579323FCD60F00634B31 /* PocketSVG.framework */; };
2020
7F53579723FCD62A00634B31 /* PocketSVG.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7F53579323FCD60F00634B31 /* PocketSVG.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
21+
7F6ED7E024074B8E0079A14F /* ExampleARSCNViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F6ED7DF24074B8E0079A14F /* ExampleARSCNViewManager.m */; };
2122
7FDD52672400E7A000CC0904 /* art.scnassets in Resources */ = {isa = PBXBuildFile; fileRef = 7FDD52662400E7A000CC0904 /* art.scnassets */; };
2223
89B0909A2BE3D812E139EA70 /* libPods-RNWebRTCARExample-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 26B1CAA6CB7697A05C157EE8 /* libPods-RNWebRTCARExample-tvOS.a */; };
2324
8ADC3F819262FE7D8BA12992 /* libPods-RNWebRTCARExample-tvOSTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 075370F613C3C04B90D431A5 /* libPods-RNWebRTCARExample-tvOSTests.a */; };
@@ -139,6 +140,8 @@
139140
7F53578723FCD60F00634B31 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
140141
7F53578823FCD60F00634B31 /* MacDemo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacDemo.swift; sourceTree = "<group>"; };
141142
7F53578923FCD60F00634B31 /* PocketSVG.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = PocketSVG.podspec; sourceTree = "<group>"; };
143+
7F6ED7DE24074B7B0079A14F /* ExampleARSCNViewManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExampleARSCNViewManager.h; sourceTree = "<group>"; };
144+
7F6ED7DF24074B8E0079A14F /* ExampleARSCNViewManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ExampleARSCNViewManager.m; sourceTree = "<group>"; };
142145
7FDD52662400E7A000CC0904 /* art.scnassets */ = {isa = PBXFileReference; lastKnownFileType = wrapper.scnassets; name = art.scnassets; path = RNWebRTCARExample/art.scnassets; sourceTree = "<group>"; };
143146
A9ACBCDE1E25148D207915D7 /* Pods-RNWebRTCARExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNWebRTCARExample.debug.xcconfig"; path = "Target Support Files/Pods-RNWebRTCARExample/Pods-RNWebRTCARExample.debug.xcconfig"; sourceTree = "<group>"; };
144147
D4924D71DCDD958C08AF9A7C /* Pods-RNWebRTCARExample-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNWebRTCARExample-tvOS.release.xcconfig"; path = "Target Support Files/Pods-RNWebRTCARExample-tvOS/Pods-RNWebRTCARExample-tvOS.release.xcconfig"; sourceTree = "<group>"; };
@@ -215,6 +218,8 @@
215218
13B07FB61A68108700A75B9A /* Info.plist */,
216219
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
217220
13B07FB71A68108700A75B9A /* main.m */,
221+
7F6ED7DE24074B7B0079A14F /* ExampleARSCNViewManager.h */,
222+
7F6ED7DF24074B8E0079A14F /* ExampleARSCNViewManager.m */,
218223
);
219224
name = RNWebRTCARExample;
220225
sourceTree = "<group>";
@@ -800,6 +805,7 @@
800805
isa = PBXSourcesBuildPhase;
801806
buildActionMask = 2147483647;
802807
files = (
808+
7F6ED7E024074B8E0079A14F /* ExampleARSCNViewManager.m in Sources */,
803809
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
804810
13B07FC11A68108700A75B9A /* main.m in Sources */,
805811
);

packages/RNWebRTCARExample/js/AR.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
import React from 'react'
22
import { StyleSheet } from 'react-native'
33
import { ARKit } from 'react-native-arkit'
4+
import ARFaceTracking from './Custom/AR'
45

56
const styles = StyleSheet.create({
67
container: { flex: 1, backgroundColor: 'black' },
78
})
89

910
export default function AR(props) {
11+
const { faceTracking } = props
12+
if (faceTracking) {
13+
return <ARFaceTracking style={styles.container} />
14+
}
1015
return (
1116
<ARKit
1217
style={styles.container}

packages/RNWebRTCARExample/js/App.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export default function App() {
1818
const [setting, setSetting] = useState({
1919
debug: __DEV__,
2020
arEnabled: ar,
21+
faceTracking: false,
2122
})
2223
const [localStreamURL, setLocalStreamURL] = useState(null)
2324
const [remoteStreams, setRemoteStreams] = useState({})
@@ -50,7 +51,7 @@ export default function App() {
5051
setRemoteStreams({})
5152
client.close()
5253
}
53-
}, [setting.roomId, setting.arEnabled])
54+
}, [setting.roomId, setting.arEnabled, setting.faceTracking])
5455

5556
const handleSettingChange = useCallback(
5657
(name, value) =>
@@ -64,7 +65,7 @@ export default function App() {
6465
return (
6566
<>
6667
{setting.arEnabled ? (
67-
<AR debug={setting.debug} />
68+
<AR debug={setting.debug} faceTracking={setting.faceTracking} />
6869
) : (
6970
<RTCView streamURL={localStreamURL} style={styles.container} />
7071
)}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React, { useEffect } from 'react'
2+
import { requireNativeComponent, NativeModules } from 'react-native'
3+
4+
const ExampleARSCNView = requireNativeComponent('ExampleARSCNView')
5+
6+
const {
7+
injectARSession,
8+
revertARSession,
9+
} = NativeModules.ExampleARSCNViewManager
10+
11+
export default function(props) {
12+
useEffect(() => {
13+
injectARSession()
14+
return () => revertARSession()
15+
}, [])
16+
return <ExampleARSCNView {...props} />
17+
}

packages/RNWebRTCARExample/js/Setting.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ import {
1111
Linking,
1212
} from 'react-native'
1313
import { Modalize } from 'react-native-modalize'
14-
import { isARWorldTrackingSupported } from 'react-native-webrtc-ar-session'
14+
import {
15+
isARWorldTrackingSupported,
16+
isARFaceTrackingSupported,
17+
} from 'react-native-webrtc-ar-session'
1518
import AsyncStorage from '@react-native-community/async-storage'
1619
import debounce from 'lodash.debounce'
1720

@@ -80,6 +83,7 @@ export default function Settings(props) {
8083
const [roomId, setRoomId] = useState('')
8184
const [debug, setDebug] = useState(__DEV__)
8285
const [arEnabled, setAREnabled] = useState(true)
86+
const [faceTracking, setFaceTracking] = useState(false)
8387

8488
useEffect(() => {
8589
AsyncStorage.getItem('roomId').then(setRoomId)
@@ -99,6 +103,10 @@ export default function Settings(props) {
99103
onChange('arEnabled', arEnabled)
100104
}, [onChange, arEnabled])
101105

106+
useEffect(() => {
107+
onChange('faceTracking', faceTracking)
108+
}, [onChange, faceTracking])
109+
102110
const handleRoomIdChange = useMemo(
103111
() =>
104112
debounce(id => {
@@ -151,6 +159,15 @@ export default function Settings(props) {
151159
<Switch value={debug} onValueChange={setDebug} />
152160
</TouchableOpacity>
153161
)}
162+
{isARFaceTrackingSupported && (
163+
<TouchableOpacity
164+
style={styles.switch}
165+
onPress={() => setFaceTracking(val => !val)}
166+
>
167+
<Text style={styles.field}>Switch Face Tracking Example</Text>
168+
<Switch value={faceTracking} onValueChange={setFaceTracking} />
169+
</TouchableOpacity>
170+
)}
154171
<View style={styles.textContainer}>
155172
<Text style={styles.text}>Visit</Text>
156173
<TouchableOpacity onPress={() => Linking.openURL(readme)}>

packages/react-native-webrtc-ar-session/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ You can have native ARSCNView setup without `react-native-arkit`:
4444
[RNWebRTCARSession setArView:__your_arscnview_here__];
4545
```
4646
47+
[Example](https://github.com/jhen0409/rn-webrtc-arkit-integration/blob/master/packages/RNWebRTCARExample/ios/ExampleARSCNViewManager.m)
48+
4749
## License
4850
4951
[MIT](https://github.com/jhen0409/rn-webrtc-arkit-integration/blob/master/LICENSE.md)

0 commit comments

Comments
 (0)