├── .gitignore
├── ARAnimatedProvider.js
├── ARMonoView.js
├── ARPositionProvider.js
├── ARProjectedView.js
├── ARSessionProvider.js
├── ARTouchProvider.js
├── ARTouchableMonoView.js
├── ARTrackingProvider.js
├── README.md
├── RNSwiftBridge.js
├── _config.yml
├── components
├── ARBox.js
├── ARCapsule.js
├── ARCone.js
├── ARCylinder.js
├── ARGeometry.js
├── ARLight.js
├── ARMaterial.js
├── ARMaterialProperty.js
├── ARMaterials.js
├── ARModel.js
├── ARNode.js
├── ARPlane.js
├── ARProjectedPointProvider.js
├── ARPyramid.js
├── ARSKLabel.js
├── ARSKScene.js
├── ARSKVideo.js
├── ARScene.js
├── ARShape.js
├── ARSphere.js
├── ARText.js
├── ARTorus.js
├── ARTube.js
├── ARZoomResponder.js
├── old
│ └── ARSprite.js
└── propTypes.js
├── index.js
├── ios
├── react_native-arkit-swift-Bridging-Header.h
├── react_native-arkit-swift.xcodeproj
│ ├── bob
│ └── project.pbxproj
├── react_native-arkit-swift
│ ├── ARExtension.swift
│ ├── ARMonoview.swift
│ ├── ARMonoviewManager.swift
│ ├── ARPrimaryView.swift
│ ├── ARPrimaryViewManager.swift
│ ├── ARProjectedView.swift
│ ├── ARProjectedViewManager.swift
│ ├── ARSceneManager.swift
│ ├── ARSecondaryView.swift
│ └── ARSecondaryViewManager.swift
└── rn-swift-bridge.m
├── package.json
└── yarn-error.log
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | yarn.lock
3 | ios/.DS_Store
4 | *.xcworkspacedata
5 | *.xcuserstate
6 | *.xcbkptlist
7 | ios/react_native-arkit-swift.xcodeproj/xcuserdata/ray.xcuserdatad/xcschemes/xcschememanagement.plist
8 | ios/react_native-arkit-swift/.DS_Store
9 | .DS_Store
10 | yarn-error.log
11 | *.log
12 | yarn-error.log
13 | convert.js
14 |
--------------------------------------------------------------------------------
/ARAnimatedProvider.js:
--------------------------------------------------------------------------------
1 | import React, { createContext, Component } from "react";
2 | import PropTypes from "prop-types";
3 | import { setAnimation } from "./RNSwiftBridge";
4 | const { Provider, Consumer } = createContext({});
5 | class ARAnimatedProvider extends Component {
6 | providerValue = {
7 | willNativeUpdate: this.willNativeUpdate.bind(this),
8 | didNativeUpdate: this.didNativeUpdate.bind(this)
9 | };
10 | render() {
11 | return ;
12 | }
13 | async willNativeUpdate() {
14 | await setAnimation(
15 | parseFloat(this.props.milliseconds) / 1000.0,
16 | this.props.easing
17 | );
18 | }
19 | async didNativeUpdate() {
20 | //Do nothing
21 | }
22 | }
23 | ARAnimatedProvider.defaultProps = {
24 | milliseconds: 250,
25 | easing: "inout"
26 | };
27 | ARAnimatedProvider.propTypes = {
28 | milliseconds: PropTypes.number,
29 | easing: PropTypes.string
30 | };
31 | export { ARAnimatedProvider, Consumer as ARAnimatedConsumer };
32 | export default ARAnimatedProvider;
33 |
--------------------------------------------------------------------------------
/ARMonoView.js:
--------------------------------------------------------------------------------
1 | import { ARMonoView as NativeMonoView } from "./RNSwiftBridge";
2 | import PropTypes from "prop-types";
3 | import React, { Component } from "react";
4 | import { ARSessionConsumer, ARSessionProvider } from "./ARSessionProvider";
5 | class ARBaseMonoView extends Component {
6 | render() {
7 | return (
8 |
9 | {value => {
10 | const { isStarted } = value;
11 | if (typeof isStarted === "undefined") {
12 | return (
13 |
20 |
21 |
22 | );
23 | } else
24 | return [
25 | ,
30 | typeof this.props.children == "function" ? (
31 |
32 | {value => {
33 | return this.props.children(value);
34 | }}
35 |
36 | ) : this.props.children ? (
37 | this.props.children
38 | ) : null
39 | ];
40 | }}
41 |
42 | );
43 | }
44 | componentDidMount() {
45 | if (typeof this.props.start == "function") this.props.start();
46 | }
47 | componentWillUnmount() {
48 | if (typeof this.props.stop == "function") this.props.stop();
49 | }
50 | }
51 | ARBaseMonoView.propTypes = {
52 | preview: PropTypes.bool,
53 | start: PropTypes.func,
54 | stop: PropTypes.func,
55 | debugMode: PropTypes.bool
56 | };
57 | ARBaseMonoView.defaultProps = {
58 | preview: true,
59 | debugMode: false
60 | };
61 | const ARMonoView = props => (
62 |
63 | {({ start, stop }) => (
64 |
65 | )}
66 |
67 | );
68 | ARMonoView.propTypes = { ...ARBaseMonoView.propTypes };
69 | export default ARMonoView;
70 |
--------------------------------------------------------------------------------
/ARPositionProvider.js:
--------------------------------------------------------------------------------
1 | import React, { Component, createContext } from "react";
2 | import {
3 | subscribeToARPositionChange,
4 | setPOVSensitivity,
5 | setPOVOrientationSensitivity
6 | } from "./RNSwiftBridge";
7 | import PropTypes from "prop-types";
8 | const { Provider, Consumer: ARPositionConsumer } = createContext({
9 | position: { x: 0, y: 0, z: 0 },
10 | orientation: {}
11 | });
12 | class ARPositionProvider extends Component {
13 | state = {
14 | providerValue: {
15 | position: { x: 0, y: 0, z: 0 },
16 | orientation: { x: 0 }
17 | },
18 | positionSensitivity: -1,
19 | orientationSensitivity: -1
20 | };
21 | positionChange = null;
22 | componentDidMount() {
23 | this.positionChange = subscribeToARPositionChange(
24 | this.onPositionChange.bind(this)
25 | );
26 | }
27 | componentWillUnmount() {
28 | if (this.positionChange) this.positionChange.remove();
29 | }
30 | onPositionChange(data) {
31 | this.setState({ providerValue: data });
32 | if (typeof this.props.onPositionChange == "function")
33 | this.props.onPositionChange(data);
34 | }
35 | render() {
36 | return (
37 |
38 | {typeof this.props.children == "function" ? (
39 |
40 | {value => {
41 | return this.props.children(value);
42 | }}
43 |
44 | ) : (
45 | this.props.children
46 | )}
47 |
48 | );
49 | }
50 | static getDerivedStateFromProps(nextProps, prevState) {
51 | var ret = prevState;
52 | if (prevState.positionSensitivity != nextProps.positionSensitivity) {
53 | setPOVSensitivity(nextProps.positionSensitivity);
54 | ret.positionSensitivity = nextProps.positionSensitivity;
55 | }
56 | if (prevState.orientationSensitivity != nextProps.orientationSensitivity) {
57 | setPOVOrientationSensitivity(nextProps.orientationSensitivity);
58 | ret.orientationSensitivity = nextProps.orientationSensitivity;
59 | }
60 | return ret;
61 | }
62 | }
63 | ARPositionProvider.defaultProps = {
64 | positionSensitivity: 0.01,
65 | orientationSensitivity: 0.05
66 | };
67 | ARPositionProvider.propTypes = {
68 | onPositionChange: PropTypes.func,
69 | positionSensitivity: PropTypes.number,
70 | orientationSensitivity: PropTypes.number
71 | };
72 | export { ARPositionProvider, ARPositionConsumer };
73 | export default ARPositionProvider;
74 |
--------------------------------------------------------------------------------
/ARProjectedView.js:
--------------------------------------------------------------------------------
1 | import PropTypes from "prop-types";
2 | import React from "react";
3 | import { ARSessionConsumer } from "./ARSessionProvider";
4 | import { ARNodeConsumer } from "./components/ARNode";
5 | import { adopt } from "react-adopt";
6 | import { ARProjectedView as SwiftARProjectedView } from "./RNSwiftBridge";
7 |
8 | const ARBaseProjectedView = props => (
9 |
13 | );
14 | const Adoptee = adopt({
15 | session: ,
16 | node:
17 | });
18 | const ARProjectedView = props => {
19 | return (
20 |
21 | {({ session: { isStarted }, node: { nodeID } }) => {
22 | if (!isStarted) return null;
23 | return ;
24 | }}
25 |
26 | );
27 | };
28 | ARProjectedView.propTypes = {
29 | parentNode: PropTypes.string
30 | };
31 | export default ARProjectedView;
32 |
--------------------------------------------------------------------------------
/ARSessionProvider.js:
--------------------------------------------------------------------------------
1 | import React, { Component, createContext } from "react";
2 | import PropTypes from "prop-types";
3 | import { clear, pause, resume, setWorldTracking } from "./RNSwiftBridge";
4 | const { Provider, Consumer: ARSessionConsumer } = createContext({});
5 | class ARSessionProvider extends Component {
6 | state = {
7 | providerValue: this.setProviderValue(true),
8 | alignment: "gravity",
9 | isStarted: false
10 | };
11 | constructor(props) {
12 | super(props);
13 | this.state.providerValue = this.setProviderValue(true);
14 | }
15 | start() {
16 | (async () => {
17 | try {
18 | await resume();
19 | } catch (e) {}
20 | try {
21 | await clear();
22 | } catch (e) {}
23 | this.setState({ isStarted: true }, () => {
24 | this.setProviderValue();
25 | });
26 | })();
27 | }
28 | stop() {
29 | pause();
30 | }
31 | setProviderValue(skipState) {
32 | const providerValue = {
33 | isStarted: !!(this.state && this.state.isStarted),
34 | start: this.start.bind(this),
35 | stop: this.stop.bind(this)
36 | };
37 | if (!skipState) this.setState({ providerValue });
38 | return providerValue;
39 | }
40 | static getDerivedStateFromProps(nextProps, prevState) {
41 | var ret = prevState;
42 | if (nextProps.alignment && nextProps.alignment != prevState.alignment) {
43 | if (prevState.isStarted) {
44 | ret.alignment = nextProps.alignment;
45 | setWorldTracking(ret.alignment);
46 | }
47 | }
48 | return ret;
49 | }
50 | render() {
51 | return (
52 |
53 | {typeof this.props.children == "function" ? (
54 | {this.props.children}
55 | ) : (
56 | this.props.children
57 | )}
58 |
59 | );
60 | }
61 | }
62 | ARSessionProvider.propTypes = {
63 | alignment: PropTypes.string
64 | };
65 | ARSessionProvider.defaultProps = {
66 | alignment: "gravity"
67 | };
68 | export { ARSessionProvider, ARSessionConsumer };
69 | export default ARSessionProvider;
70 |
--------------------------------------------------------------------------------
/ARTouchProvider.js:
--------------------------------------------------------------------------------
1 | import React, { Component, createContext } from "react";
2 | import { doTap } from "./RNSwiftBridge";
3 | const { Provider, Consumer: ARTouchConsumer } = createContext({});
4 | class ARTouchProvider extends Component {
5 | registeredNodes = {};
6 | constructor(props) {
7 | super(props);
8 | this.state = {
9 | providerValue: {
10 | registerNode: this.registerNode.bind(this),
11 | removeNode: this.removeNode.bind(this),
12 | triggerAtLocation: this.triggerAtLocation.bind(this)
13 | }
14 | };
15 | }
16 | async getNodesFromLocation(x, y) {
17 | const out = await doTap(x, y);
18 | return out;
19 | }
20 | async triggerAtLocation(prop, x, y) {
21 | const out = await this.getNodesFromLocation(x, y);
22 | if (out.nodes && out.nodes.length) {
23 | for (var x = 0; x < out.nodes.length; x++) {
24 | if (this.triggerProp(out.nodes[x], prop)) break;
25 | }
26 | }
27 | }
28 | triggerProp(nodeID, propName) {
29 | const node = this.registeredNodes[nodeID];
30 | if (
31 | node &&
32 | node.props &&
33 | node.props[propName] &&
34 | typeof node.props[propName] == "function"
35 | ) {
36 | node.props[propName]();
37 | return true;
38 | }
39 | return false;
40 | }
41 | registerNode(id, node) {
42 | this.registeredNodes[id] = node;
43 | }
44 | removeNode(id) {
45 | delete this.registeredNodes[id];
46 | }
47 | render() {
48 | return (
49 |
50 | {typeof this.props.children == "function" ? (
51 | {this.props.children}
52 | ) : (
53 | this.props.children
54 | )}
55 |
56 | );
57 | }
58 | }
59 | export { ARTouchProvider, ARTouchConsumer };
60 | export default ARTouchProvider;
61 |
--------------------------------------------------------------------------------
/ARTouchableMonoView.js:
--------------------------------------------------------------------------------
1 | import { TouchableWithoutFeedback } from "react-native";
2 | import React, { Component } from "react";
3 | import ARMonoView from "./ARMonoView";
4 | import { ARTouchProvider } from "./ARTouchProvider";
5 | const ARTouchableMonoView = props => (
6 |
7 | {({ triggerAtLocation }) => {
8 | return (
9 | {
11 | if (triggerAtLocation)
12 | triggerAtLocation("onPress", locationX, locationY);
13 | }}
14 | onPressIn={({ nativeEvent: { locationX, locationY } }) => {
15 | if (triggerAtLocation)
16 | triggerAtLocation("onPressIn", locationX, locationY);
17 | }}
18 | onPressOut={({ nativeEvent: { locationX, locationY } }) => {
19 | if (triggerAtLocation)
20 | triggerAtLocation("onPressOut", locationX, locationY);
21 | }}
22 | >
23 |
24 |
25 | );
26 | }}
27 |
28 | );
29 | ARTouchableMonoView.propTypes = ARMonoView.propTypes;
30 | export default ARTouchableMonoView;
31 |
--------------------------------------------------------------------------------
/ARTrackingProvider.js:
--------------------------------------------------------------------------------
1 | import React, { Component, createContext } from "react";
2 | import PropTypes from "prop-types";
3 | import {
4 | getAnchors,
5 | setImageDetection,
6 | subscribeToARImageEvent,
7 | subscribeToARPlaneEvent,
8 | setPlaneDetection,
9 | addRecognizerImage,
10 | removeRecognizerImage,
11 | subscribeToARCameraState
12 | } from "./RNSwiftBridge";
13 | const { Provider, Consumer: ARTrackingConsumer } = createContext();
14 | class ARTrackingProvider extends Component {
15 | state = {
16 | planeDetection: "none",
17 | imageDetection: false,
18 | transition: 0,
19 | anchors: {},
20 | providerValue: this.setProviderValue(true),
21 | trackingLevel: "notAvailable"
22 | };
23 | constructor(props) {
24 | super(props);
25 | this.state.providerValue = this.setProviderValue(true);
26 | }
27 | setProviderValue(skipState) {
28 | const providerValue = {
29 | anchors: this.state ? this.state.anchors : {},
30 | trackingLevel: this.state ? this.state.trackingLevel : "notAvailable"
31 | };
32 | if (!skipState)
33 | this.setState({ providerValue }, () => {
34 | if (this.props.onUpdateAnchors)
35 | this.props.onUpdateAnchors(this.state.providerValue.anchors);
36 | });
37 | return providerValue;
38 | }
39 | render() {
40 | return (
41 |
42 | {typeof this.props.children == "function" ? (
43 | {this.props.children}
44 | ) : (
45 | this.props.children
46 | )}
47 |
48 | );
49 | }
50 | static getDerivedStateFromProps(nextProps, prevState) {
51 | const ret = prevState ? prevState : {};
52 | if (!ret.todos) ret.todos = {};
53 | if (nextProps.planeDetection != prevState.planeDetection) {
54 | ret.todos["setPlaneDetection"] = nextProps.planeDetection;
55 | ret.planeDetection = nextProps.planeDetection;
56 | }
57 | if (nextProps.imageDetection != prevState.imageDetection) {
58 | ret.todos["setImageDetection"] = nextProps.imageDetection;
59 | ret.imageDetection = nextProps.imageDetection;
60 | }
61 | if (ret.imageDetection && propDiff(nextProps.images, prevState.images)) {
62 | ret.todos["setImages"] = true;
63 | ret.images = nextProps.images;
64 | }
65 | if (!ret.todos || Object.keys(ret.todos) == 0) {
66 | delete ret.todos;
67 | }
68 | return ret;
69 | }
70 | cameraStateDetection = null;
71 | componentDidUpdate() {
72 | this.manageTodos();
73 | this.cameraStateDetection = subscribeToARCameraState(
74 | this.updateCameraState.bind(this)
75 | );
76 | }
77 | componentDidMount() {
78 | this.manageTodos();
79 | if (this.cameraStateDetection) this.cameraStateDetection.remove();
80 | this.cameraStateDetection = null;
81 | }
82 | manageTodos() {
83 | if (this.state.todos) {
84 | Object.keys(this.state.todos).forEach(k => {
85 | if (typeof this[k] == "function") {
86 | this[k](this.state.todos[k]);
87 | }
88 | });
89 | this.setState({ todos: null }, () => {
90 | this.setProviderValue();
91 | });
92 | }
93 | }
94 | planeDetection = null;
95 | async setPlaneDetection(newValue) {
96 | if (["horizontal", "vertical", "both"].indexOf(newValue) > -1) {
97 | await setPlaneDetection(newValue);
98 | this.planeDetection = subscribeToARPlaneEvent(
99 | this.updatePlanes.bind(this)
100 | );
101 | } else if (this.planeDetection) {
102 | await setPlaneDetection("none");
103 | this.planeDetection.remove();
104 | this.planeDetection = null;
105 | }
106 | }
107 | imageDetection = null;
108 | async setImageDetection(newValue) {
109 | await setImageDetection(!!newValue);
110 | if (newValue) {
111 | this.imageDetection = subscribeToARImageEvent(
112 | this.updateImages.bind(this)
113 | );
114 | }
115 | if (newValue) addImageDetection(this.updateImages.bind(this));
116 | else if (this.imageDetection) {
117 | this.imageDetection.remove();
118 | this.imageDetection = null;
119 | }
120 | }
121 | registeredImages = {};
122 | setImages() {
123 | const newKeys = this.state.images
124 | ? Object.keys(this.state.images).filter(k => {
125 | return !this.registeredImages[k];
126 | })
127 | : [];
128 | const deadKeys = this.registeredImages
129 | ? Object.keys(this.registeredImages).filter(k => {
130 | return !this.state.images[k];
131 | })
132 | : [];
133 | (async () => {
134 | await Promise.all(
135 | newKeys.map(k => {
136 | const { width, url } = this.state.images[k];
137 | return addRecognizerImage(url, k, width);
138 | })
139 | );
140 | newKeys.forEach(k => {
141 | this.registeredImages[k] = this.state.images[k];
142 | });
143 | if (deadKeys.length) {
144 | await Promise.all(
145 | deadKeys.map(k => {
146 | return removeRecognizerImage(k);
147 | })
148 | );
149 | this.setState(({ images }) => {
150 | deadKeys.forEach(k => {
151 | delete images[k];
152 | });
153 | return { images: { ...images } };
154 | });
155 | }
156 | })();
157 | }
158 | async updatePlanes(planeData) {
159 | const data = planeData && planeData.data;
160 | if (!data) {
161 | const anchors = cleanAnchors(await getAnchors(data));
162 | this.setState({ anchors: anchors }, () => {
163 | this.setProviderValue();
164 | });
165 | } else
166 | switch (data.key) {
167 | case "planeAnchorAdded":
168 | case "planeAnchorChanged":
169 | const k = data.id;
170 | const anchor = cleanAnchor(data.anchor);
171 | if (
172 | !this.state.anchors[k] ||
173 | propDiff(this.state.anchors[k], anchor, cleanAnchor)
174 | ) {
175 | this.setState(
176 | ({ anchors }) => {
177 | return { anchors: { ...anchors, [k]: anchor } };
178 | },
179 | () => {
180 | this.setProviderValue();
181 | }
182 | );
183 | }
184 | break;
185 | case "planeAnchorRemoved":
186 | default:
187 | const anchors = cleanAnchors(await getAnchors(data));
188 | this.setState({ anchors: anchors }, () => {
189 | this.setProviderValue();
190 | });
191 | }
192 | }
193 | async updateImages(data) {
194 | const anchors = await getAnchors(data);
195 | this.setState({ anchors: anchors }, () => {
196 | this.setProviderValue();
197 | });
198 | }
199 | async updateCameraState(data) {
200 | this.setState({ trackingLevel: data }, () => {
201 | this.setProviderValue();
202 | });
203 | }
204 | }
205 | ARTrackingProvider.propTypes = {
206 | planeDetection: PropTypes.string,
207 | imageDetection: PropTypes.bool,
208 | onUpdateAnchors: PropTypes.func,
209 | images: PropTypes.object
210 | };
211 | export { ARTrackingProvider, ARTrackingConsumer };
212 | export default ARTrackingProvider;
213 | const cleanAnchors = o => {
214 | var out = {};
215 | if (!o) return out;
216 | Object.keys(o).forEach(k => {
217 | const v = o[k];
218 | out[k] = cleanAnchor(v);
219 | });
220 | return out;
221 | };
222 | const cleanAnchor = v => {
223 | var out = {};
224 | if (!v) return out;
225 | if (v.plane) {
226 | if (v.plane.width)
227 | v.plane.width = parseFloat(parseFloat(v.plane.width).toFixed(1));
228 | if (v.plane.height)
229 | v.plane.height = parseFloat(parseFloat(v.plane.height).toFixed(1));
230 | }
231 | return v;
232 | };
233 | const propDiff = (a, b, filterFunc) => {
234 | if (a === b) return false;
235 | if ((a && !b) || (!a && b)) return true;
236 | if (!a && !b) return false;
237 | const af = filterFunc ? filterFunc(a) : a;
238 | const bf = filterFunc ? filterFunc(b) : b;
239 |
240 | const afk = Object.keys(af);
241 | const bfk = Object.keys(bf);
242 | if (afk.length != bfk.length) return true;
243 | if (
244 | afk.filter(k => {
245 | return bfk.indexOf(k) === -1;
246 | }).length
247 | )
248 | return true;
249 | if (
250 | afk.filter(k => {
251 | return bf[k] != af[k];
252 | }).length
253 | )
254 | return true;
255 | };
256 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-reality
2 |
3 | A React-based, JSX-centric way of interacting with Augmented Reality. Make the world your provider.
4 |
5 | Currently IOS-Only, but SceneForm may change that!
6 |
7 | ## Key Features
8 |
9 | - Primitives to give high control over every aspect. Makes animations so much easier to have nodes not attached to geometries
10 | - Layout Animations via ``
11 | - Provider-based (render prop!) tracking of self ``, screen-touch on `` and both images and planes via ``
12 | - Support for touch events at the node level via onPress, onPressIn, and onPressOut events. Registered only if using a touchablemonoview
13 | - Support for mixing in scenes and models. Import Scenekit-compatible SCN and DAE via `` and add models (like from Google Poly) via ``.
14 | - Support for mixing in multiple 2-D SpriteKit `` with composed primitives and adding them to an ``. A great way for rendering images, video and text(!) in space and performantly.
15 |
16 | ## 15-second installation: `react-reality-cli`
17 |
18 | ```bash
19 | yarn global add rhdeck/react-reality-cli # or npm i g react-reality-cli
20 | react-reality init myreality # of course, replace myreality with your preferred name
21 | cd myreality
22 | react-reality run-ios --device # react-reality acts like react-native inside a RR/RN project
23 | code .
24 | ```
25 |
26 | _Note_ This installer utilizes [react-native-setdevteam](https://npmjs.com/package/react-native-setdevteam). If you have not used it before, it will ask you either to input your developer team ID or to give permission to find it for you in another project. This is necessary to sign your app and test on the phone.
27 |
28 | _Another Note_ This installer utilizes [react-native-bundlebase](https://npmjs.com/pacakge/react-native-bundlebase). If you have not used this package before, it will ask you for the base name you want to use for your app bundles. Your bundle then becomes [projectname].[bundle base]. This maintains uniqueness that allows you to more easily deploy to your device.
29 |
30 | Happy AR coding.
31 |
32 | ## 1-minute Installation: `react-native link`
33 |
34 | ```
35 | react-native init myreality
36 | cd myreality
37 | yarn add \
38 | rhdeck/react-reality \
39 | react-native-swift \
40 | react-native-pod
41 | react-native link
42 | ```
43 |
44 | Since ARKit development requires iOS 11, the camera, and signing privileges to get onto device, I also recommend:
45 |
46 | ```
47 | yarn add \
48 | react-native-fix-ios-version \
49 | react-native-camera-ios-enable \
50 | react-native-setdevteam
51 | react-native setdevteam
52 | react-native link
53 | ```
54 |
55 | Copy the sample code at the bottom of this file to your App.js to try it out. But the `react-reality-cli` approach is a lot cleaner.
56 |
57 | ## Extensions
58 |
59 | - [`react-reality-cli`](https://github.com/rhdeck/react-reality-cli): Command line interface for rapidly spinning up and managing react-reality projects
60 | - [`react-reality-holokit`](https://github.com/rhdeck/react-reality-holokit): Implementation of headset view to use the holokit by Amber Garage
61 | - [`react-reality-rnarkit-bridge`](https://github.com/rhdeck/react-reality-rnarkit-bridge): Implementing the `react-native-arkit` API on top of the `react-reality` framework.
62 |
63 | # Reference
64 |
65 | ## Views
66 |
67 | ### ARMonoView
68 |
69 | A "magic glass" renderer of both the real and virtual space from your point of view.
70 |
71 | Will auto-create a `` if it is not already the child of one.
72 |
73 | #### Props
74 |
75 | If implemented without a wrapping `` it takes the props of `` most importantly `alignment`.
76 |
77 | Otherwise, it's a View. No special (public) props.
78 |
79 | #### Sample
80 |
81 | ```javascript
82 |
83 |
84 |
85 | ```
86 |
87 | ### ARTouchableMonoView
88 |
89 | Like `ARMonoView` but adds touchability, so that descendant nodes can implement touch event handlers.
90 |
91 | Will auto-create a `` if it is not already the child of one.
92 |
93 | #### Props
94 |
95 | If implemented without a wrapping `` it takes the props of `` most importantly `alignment`.
96 |
97 | Otherwise, it's a View. No special (public) props.
98 |
99 | #### Sample
100 |
101 | ```xml
102 |
103 |
104 | ...Other nodes rendered
105 | {console.log("I got pressed"}>
106 | ...Geometries, etc
107 |
108 |
109 |
110 | ```
111 |
112 | ### ARProjectedView
113 |
114 | Mount to a node in the 3D space, it will show a view with the origin tied to that point. So if you turn away from that direction it will hide, and otherwise it floats on top where you want it.
115 |
116 | _Note_ that it sets the origin and does not clip boundaries, so if you want to "center" on the target point in space, set your "top" and "left" of the view to be negative, as in the sample.
117 |
118 | _Also Note_ Any view will show **on top** of virtual 3-d objects, even when the node the view is mounted on is "behind" them. For diagetic fidelity, use a plane mounted in space instead, such as the `` from `react-reality-components`
119 |
120 | #### Props
121 |
122 | - `parentNode`: ID of the node to which it should attach. Note that just putting the component as child/descendant of an `` will take care of this.
123 |
124 | #### Sample
125 |
126 | ```javascript
127 |
128 |
129 |
130 | See me over here, but not anywhere else
131 |
132 |
133 | ```
134 |
135 | ## Providers
136 |
137 | React Reality is built with React 16.3 contexts implemented as a first-class design pattern. All providers allow you to control how the environment will operate, and by default they include their own consumer if their child is a function.
138 |
139 | ### ARSessionProvider
140 |
141 | Manages the augmented reality session. Note that no nodes are rendered until the session starts.
142 |
143 | #### Props
144 |
145 | - `alignment`: How the system should think about x/y/z when start up the AR environment. The device will be the origin - the question is whether the other axes are based on:
146 | - `gravity` in which case y is down-to-up relative to Earth's gravity but x and z are relative to whichever way the phone is pointing at the start of the session,
147 | - `compass` in which z is south-to-north and x is west-to-east or
148 | - `camera` in which they are all based on the orientation of the device itself.
149 | (Default: `gravity`)
150 |
151 | #### Sample
152 |
153 | ```xml
154 |
155 | {Well-aligned nodes!}
156 |
157 | ```
158 |
159 | ### ARPositionProvider
160 |
161 | Tracks changes in the position of the primary point of view For ``, this is just the position of the device itself.
162 |
163 | If the immediate child is a function, the provider will wrap it in an `` to pass the function those arguments.
164 |
165 | #### Props
166 |
167 | - `sensitivity`: the required observed change, in meters, in any direction to trigger either the `onPositionChange` prop or a re-fire of the `` render prop. (Default: 0.01 - one centimeter)
168 | - `onPositionChange`: fires every time the position changes by more the designated sensitivity. Contains one argument with a `position` object (x,y,z) and an `orientation` (x,y,z,w)
169 |
170 | #### Sample
171 |
172 | ```javascript
173 | {
176 | console.log("my new lateral position is ", position.x);
177 | }}
178 | > {({position, orientation})=>{
179 | // ... Nodes that are dependant on where I am...
180 | }}
181 | ```
182 |
183 | ### ARTrackingProvider
184 |
185 | Detects and tracks planes and images (markers) in space, providing what's found via ``
186 |
187 | #### Props
188 |
189 | - `planeDetection`: Whether to detect planes and if so what kind., Values: "horizontal", "vertical", "both", "none" (Default: "none")
190 | - `imageDetection`: Whether to detect images defined in the images prop. Note that if there are no images in the images prop, this is not helpful. (Default: false)
191 | - `images`: Object as key-value store of the name of the image you want to hear about, and the an object with members `{url, width}`. `url` is URL to an ordinary image file. `width` is the width of the image in the real world, in meters. (it figures out height from the size ratio of the image itself). Note that this does not require any of the precompiled referenceImage stuff to work - just pass a PNG or something.
192 | - `onUpdateAnchors`: event to fire whenever the provider gets notice of a change, addition or removal of a plane or image, depending on what detection is activated. Basically fires with the same argument and under the same circumstances as the ``.
193 |
194 | #### Sample
195 |
196 | ```javascript
197 | {
207 | console.log("my current anchor list is", anchors);
208 | }}
209 | />
210 | ```
211 |
212 | ### ARAnimatedProvider
213 |
214 | Layout animations for AR! Declaratively define a transition time for going from one declared layout state to another. Applies to materials, geometries and nodes descending from this node.
215 |
216 | _Note_: A good way to set animation at one point but not for other descendants is to implement another intervening `` below it
217 |
218 | #### Properties
219 |
220 | - `milliseconds` Transition time in ms (Default: 250 - a quarter of a second)
221 | - `easing` Easing acceleration curve. String value with four possibilities:
222 | - "in": Start slow and speed up in the beginning of the animation. (This usually looks most natural)
223 | - "out": Go at normal speed but slow down the animation at the end.
224 | - "both": Start slow, speed up, then slow down at the end.
225 | - "none": Just move at the same speed the whole time. Has the virtue of being easy to predict where everything will be at any time.
226 | (Default: "inout")
227 |
228 | #### Sample
229 |
230 | ```javascript
231 | setInterval(()=>{ this.setState({Ypos})=> return { Ypos: Ypos + 1}}, 5000)
232 | ...
233 |
234 |
237 |
238 |
239 |
242 | >
243 |
244 |
245 |
246 |
247 |
248 | ```
249 |
250 | ## Consumers
251 |
252 | ### ARPositionConsumer
253 |
254 | Context consumer for an ancestor ``. A good way to wrap the one node you want to act as your buddy.
255 |
256 | #### Argument members
257 |
258 | - `position`: Location of current POV (relative to initial origin)
259 | - `orientation`: Orientation of current POV in quaternion format (x,y,z,w)
260 |
261 | #### Sample
262 |
263 | ```javascript
264 |
265 | // ... intervening generations...
266 |
267 | {({ position, orientation }) => {
268 | return (
269 |
273 |
274 |
275 | );
276 | }}
277 |
278 |
279 | ```
280 |
281 | ### ARTrackingConsumer
282 |
283 | Consumer for the `` above.
284 |
285 | #### Argument members
286 |
287 | - `anchors`: Key-value pairs of anchors detected with names and relevant information. The key will be the name of the node you can specify as a parentNode for mounting any additional nodes. The value will contain information relevant to the anchor:
288 | - `type`: "plane" or "image"
289 | - `plane`: Size of the plane for the identified anchor (be it an image or a detected surface) as {width, height}
290 | Note that the anchors can and should be referenced as parents to nodes to anchor a node to a particular reference point.
291 | - `name`: name of the image identified (maps to the key in the images object passed to the ``(only provided for image anchors)
292 | - `alignment`: Whether the detected plane is horizontal or vertical. This informs what orientation change you might want to apply to mounted nodes. (only provided for plane anchors)
293 |
294 | #### Sample
295 |
296 | ```javascript
297 |
298 | // ... intervening nodes
299 |
300 | {({anchors})=>{
301 | if(anchors.starwars) {
302 | //Render a cube two meters above a galaxy far far away
303 | return (
304 |
305 |
306 |
307 | )
308 | }
309 | }}
310 |
311 |
312 | ```
313 |
314 | ## Nodes
315 |
316 | A node represents position in space relative to their parent. A node need not have anything visible attached to it - in fact, that can be really desirable to manage animations through space, as you set up a node as a reference point and have other nodes position and move in relationship to it.
317 |
318 | ### ARNode
319 |
320 | Position in space relative to its identified parent.
321 |
322 | #### Props
323 |
324 | - `parentNode`: Node to be parent to this node in space. If not provided, assumes the nearest ancestor ``. If there is none, mounts relative to egocentric origin. (Note: this is usually only specified when you are establishing a node tree that is mounting to an exocentric anchor, like provided by the ``)
325 | - `position`: location of the node in meters relative to its parent. object of {x,y,z} (default: {x: 0, y: 0, z: 0})
326 | - `scale`: resizing this node and its descendants relative to parent node. A positive value where 1.0 means scale is same as parent. (Default: 1.0)
327 | - `opacity`: Whether this node and its descendants should be see-through. Values from 0-1.0 inclusive. 0 means invisible and 1 means opaque. (Default: 1.0)
328 | - `id`: name for the node. Referenced for parentNode publicly. Most of the time you are not setting this. (Default: randomly assigned UUID)
329 |
330 | The following all describe the pose of the node. Usually you want to use one but not all three. Orientation is most robust as a quaternion, but rotation and eulerAngles are easier to work with for newcomers.
331 |
332 | - `orientation`: pose of the node expressed as a quaternion {x,y,z,w}
333 | - `rotation`: pose of the node expressed with three degrees of freedom {x,y,z}
334 | - `eulerAngles`: pose of the node expressed as euler angles {x,y,z}. (_Hint_ while they can cause rotation lock problems in complex situations, these are easier to use than orientation quaternions for those less versed in 3D programming)
335 |
336 | The following props only work when mounted inside a ``:
337 |
338 | - `onPress`: event fired with a finger comes down and comes up again over this node on a ``
339 | - `onPressIn`: event fired when finger is pressed on a `` over this node. (usually requires a geometry mounted on this node for detection to work)
340 | - `onPressOut`: event fired when the finger is lifted from a `` over this node. (usually requires a geometry mounted on this node for detection to work)
341 |
342 | ## Geometries
343 |
344 | Geometries are generally simple shapes that can be attached to nodes. Only one geometry per node.
345 |
346 | _Note_: All size measurements are in meters. Chamfer is the concept of rounding a 3-d corner.
347 |
348 | ### ARBox
349 |
350 | Creates a rectangular hexahedron geometry. C'mon. You know what a box is. Sides: 6
351 |
352 | #### Props
353 |
354 | - `height`: Height (y-axis) of the box, in meters (default: 1.0)
355 | - `width`: Width (x-axis) of the box, in meters (default: 1.0)
356 | - `length`: Length (z-axis) of the box, in meters (default: 1.0)
357 | - `chamfer`: How much to round the corners of the box (default: 0)
358 |
359 | ### ARCapsule
360 |
361 | A pill shape. Sides: 3
362 |
363 | #### Props
364 |
365 | - `capR`: Radius of the cap on the end of the pill. (default: 0.5)
366 | - `height`: Length of the cap (basically the "tube" part would be height - (capR \* 2) (default: 1)
367 |
368 | ### ARCone
369 |
370 | Cone or a cropped/partial cone. Sides: 2 if it goes to a point, and 3 if it is cropped (e.g. if `topR` and `bottomR` are greater than 0)
371 |
372 | #### Props
373 |
374 | - `topR`: Radius exposed at top of cone. Set to 0 for the full dunce-hat (Default: 0)
375 | - `bottomR`: Radius at bottom of cone. Set to 0 for an upside-down cone. (Default: 0.5)
376 | - `height`: Height of the cone. (Default: 1)
377 |
378 | ### ARCylinder
379 |
380 | A cylinder. Sides: 3
381 |
382 | #### Props
383 |
384 | - `radius`: radius of the cylinder. (Default: 0.5)
385 | - `height`: length of the cylinder. (Default: 1)
386 |
387 | ### ARPlane
388 |
389 | A single-sided plane. Note that this is invisible from one side. Sides: 1
390 |
391 | _Hint_: This is a great geometry for mounting `` content
392 |
393 | #### Props
394 |
395 | - `width`: width of plane. (Default: 1)
396 | - `height`: height of plane. (Default: 1)
397 | - `cornerRadius`: radius of a rounded corner. (Default: 0)
398 |
399 | #### Sample
400 |
401 | ```javascript
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 | ```
412 |
413 | ### ARPyramid
414 |
415 | A Pyramid. Sides: 5
416 |
417 | #### Props
418 |
419 | - `width`: x axis of the base. (Default: 1)
420 | - `length`: z axis of the base. (Default: 1)
421 | - `height`: height (y axis) (Default: 1)
422 |
423 | ### ARShape
424 |
425 | A bezier path-based 2D shape defined with SVG and extruded into 3D space. Sides: 1 if there is no extrusion, 3 if there is no chamfer, 4 if chamfer is front or back only, and 5 if there is chamfer both front and back.
426 |
427 | This is the most complicated of the basic geometries, and most of the time you won't need to use it anyway, so don't sweat if it looks like a bit much.
428 |
429 | #### Props
430 |
431 | - `pathSvg`: SVG text representation of the path to be displayed. Required throw error if this text is not provided.
432 | - `extrusion`: depth of the extrusion. (default: 1)
433 | - `chamferMode`: Whether to apply chamfer to front (1), back, (2) both (3) or neither (0). (Default: 0)
434 | - `chamferRadius`: Radius of the chamfer if chamferMode is not 0 (default: 0)
435 |
436 | _Note_: Setting a custom bezier path for the chamfer is not supported at this time.
437 |
438 | ### ARSphere
439 |
440 | A ball. Sides: 1
441 |
442 | #### Props
443 |
444 | - `radius`: Radius of the sphere. (Default: 0.5)
445 |
446 | ### ARText
447 |
448 | Extruded text in space. Sides: 3 if no chamfer, otherwise 4
449 |
450 | #### Props
451 |
452 | - `text`: Text to be rendered
453 | - `fontName`: Name of font to be used (Defaults to system default font)
454 | - `size`: Size of the font to use (usually effects how geometrically complex the text objects will be) (Default: 12)
455 | - `depth`: z-axis of the extrusion of the text (default: 0.1)
456 | - `chamfer`: chamfer/rounding of the edges from font face to the extrusion (Default: 0)
457 |
458 | _Note_: This creates complex shapes that are highly computationally expensive to render and maintain. If you want to display diagetic text, the `` is higher-quality and lower-cost.
459 |
460 | ### ARTorus
461 |
462 | A donut. Mmm, donuts. Sides: 1
463 |
464 | #### Props
465 |
466 | - `ringR`: radius of the ring (how wide is the donut sitting on a table?) (Default: 0.5)
467 | - `pipeR`: radius of the pipe itself (how tall is the donut on the table?) (Default: 0.25)
468 |
469 | ### ARTube
470 |
471 | A tube. Sides: 4 if there is any thickness to it (e.g. a difference between `innerR` and `outerR`) , otherwise 2
472 |
473 | #### Props
474 |
475 | - `innerR`: Radius of the inside of the tube. (Default: 0.25)
476 | - `outerR`: Outer radius of the tube (Default: 0.5)
477 | - `height`: Height/length of the tube. (Default: 1)
478 |
479 | _Note_ As implied by the `height` prop, the default position of a tube is vertical. Reorient by changing orentation/rotation/eulerAngles of the containing node.
480 |
481 | ## Models
482 |
483 | Mounting complex models that come from other sources makes developing interesting AR experiences much much easier. Scenes and models get mounted to nodes of interest (such as a detected anchor) and the animations etc just work.
484 |
485 | ### ARScene
486 |
487 | A wrapper for importing pre-build SCN scenes and iOS-compatible DAE ensembles.
488 |
489 | _Note_ ARKit seems a little skittish about properly mounting textures for these scenes.
490 |
491 | Animate, move it around etc by manipulating a parent node.
492 |
493 | Comes with animations running right from the point of mount.
494 |
495 | #### Props
496 |
497 | - `path`: Local file path to the downloaded SCN or DAE file.
498 |
499 | #### Sample
500 |
501 | ```javascript
502 |
503 |
504 |
505 | ```
506 |
507 | ### ARModel
508 |
509 | A wrapper for downloaded OBJ models, such as those you can get from Google Poly. Note that it will load textures for a downloaded model from the path relative to that model, whihc means if you get the OBJ and MTL file in the same directory, you probably get all your texture goodness without further work.
510 |
511 | #### Props
512 |
513 | - `path`: Local file path to the downloaded OBJ file.
514 |
515 | #### Sample
516 |
517 | ```javascript
518 |
519 |
520 |
521 | ```
522 |
523 | ## Materials
524 |
525 | ### ARMaterial
526 |
527 | Control over the material applied to a side of a geometry. Directly calling this element is going to be much less common than just using `` for simple application to relevant sides.
528 |
529 | #### Props
530 |
531 | - `index`: the index number of the side of the geometry that this material will apply to.
532 |
533 | The rest of these props are for more advanced/subtle manipulation. Most of your control is in the `` component.
534 |
535 | - `metalness`: Number 0-1
536 | - `roughness`: Number 0-1
537 | - `blendMode`: "Add", "Subtract", "Multiply", "Screen", "Replace"
538 | - `lightingModel`: "Constant", "Blinn", "Phong", "Lambert", "PhysicallyBased"
539 | - `shaders`: Object {Geometry, Surface, LightingModel, Fragment}
540 | - `writesToDepthBuffer`: Boolean
541 | - `colorBufferWriteMask`: "All", "None", "Alpha", "Blue", "Red", "Green
542 | - `doubleSided`: Boolean
543 | - `litPerPixel`: Boolean
544 | - `transparency`: 0-1
545 | - `fillMode`: "Fill" or "Lines"
546 |
547 | **@TODO** fill in smarter descriptions of these
548 |
549 | ### ARMaterials
550 |
551 | An affordance that applies all the ARMaterialProperty child components to every face of the material. (so you can make a red cube without having to specify each side)
552 |
553 | #### Props
554 |
555 | Inherits all props from `` except for `index`.
556 |
557 | #### Sample
558 |
559 | ```xml
560 |
561 |
562 |
563 |
564 |
565 | ```
566 |
567 | ### ARMaterialProperty
568 |
569 | Material Properties define how a material interacts with light. The most common use is setting a color that will cause it to refract that spectrum. A second common use is setting an image that will be used as texture (e.g. a poster of an image).
570 |
571 | `` nodes are also where you mount your `` for placing dynamic 2-d content
572 |
573 | #### Props
574 |
575 | - `id`: Type of material property. Valid string values include "diffuse", "specular", "normal" (Default, because this is the one you will want to use most often: **diffuse**)
576 | - `color`: Color to be applied. Takes a string or a number
577 | - `path`: Path to file with texture to apply, as an alternative to setting a flat color
578 | - `intensity`: How much to apply this property (basically lower values wash out the effect/color/texture) 0.0-1.0
579 |
580 | #### Sample
581 |
582 | ```xml
583 |
584 |
585 |
586 |
587 |
588 | ```
589 |
590 | ## 2-D Content
591 |
592 | Mounting 2-D content on 3-D objects in space creates cool effects for far less compuational cost, making a smoother experience.
593 |
594 | Note all dimensions here are in pixels - the scene is stretched or compressed based on the size of the face of geometry (e.g. the `` it is mounted on.
595 |
596 | ### ARSKScene
597 |
598 | Wrapper for a 2-D scene that uses SpriteKit technology on iOS.
599 |
600 | Must be mounted to a `` See sample.
601 |
602 | #### Props
603 |
604 | - `height`: Pixel height of the SKScene. NOte that this is scaled/stretched based on the geometry this is mounted on. A small "height" on a huge plane will look fuzzy. A big "height" on a tiny plane will look sharp,but be more computational intensive than is really visible.
605 | - `width`: Pixel width of SKScene
606 | - `color`: Background color of the scene
607 |
608 | #### Sample
609 |
610 | ```javascript
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 | ```
623 |
624 | ### ARSKLabel
625 |
626 | A text label to be rendered in a ``.
627 |
628 | #### Props
629 |
630 | - `text`: Text to be rendered as a string
631 | - `position`: Offset of the center of the text box from parent SK element {x, y}
632 | - `fontName`: Font to use (Default: system default)
633 | - `fontSize`: Size of font to use. Number, not string. (Default: system default)
634 | - `fontColor`: Color to draw with
635 | - `width`: Pixel width to allocate to the text (will wrap within this pixel constraint)
636 | - `lines`: Number of lines to display in the text label (default: 1)
637 | - `lineBreak`: How to handle wrapping between lines. One of `word`, `ellipsis`, `char`. (Default: `word` for multiple-line labels and `ellipsis` when it is one line)
638 | - `allowScaling`: Whether to allow the text to scale when it is too big for the space. Basically means you can apply an arbitrarily big `fontSize` and have it fit. Boolean. (Default: true)
639 |
640 | #### Sample
641 |
642 | ```javascript
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 | ```
655 |
656 | ### ARSKVideo
657 |
658 | Play a local video. Rendered in a ``. Not super-powerful as yet, but cool to have floating TV effect!
659 |
660 | #### Props
661 |
662 | - `url`: Source of the video or stream
663 | - `path`: Path to a locally stored video (handy if managing with RNFS) (overridden by `url` if the other is specified)
664 | - `isPlaying` whether the video should be playing or not
665 | - `height` target height of the video in pixels
666 | - `width` target width of the video
667 | - `position` Offset of the center of the vide from the parent SK element {x, y}
668 |
669 | #### Sample
670 |
671 | ```javascript
672 |
673 |
674 |
675 |
676 |
677 |
683 |
684 |
685 |
686 |
687 |
688 | ```
689 |
690 | # 2-D Enhancements
691 |
692 | ## ARButton
693 |
694 | Quickly create a 2-d tappable button floating in space. It is a node, but is best mounted on a node with a bit of distance to the user. Requires viewing through `` - otherwise how would you tap it?
695 |
696 | ### Props
697 |
698 | Inherits props from `` and adds:
699 |
700 | - `title`: Title text for the button
701 | - `pressDepth`: How much to change z-position when pressed. (negative for "press-in") (Default -0.2 meters)
702 | - `highlightColor`: Color to change to when pressed. (default: purple)
703 |
704 | ## ARSign
705 |
706 | Quickly create a 2-d sign with text floating in space. Acts as a geometry. (E.g. you mount it on a node)
707 |
708 | ### Props
709 |
710 | Inherits props from `` and adds
711 | `text`: The text to display
712 |
713 | ### Example
714 |
715 | ```jsx
716 |
717 |
718 |
719 | ```
720 |
721 | **Note** An even higher-level implementation that smushes the node props in is available as ``
722 |
723 | ## ARPlaneScene
724 |
725 | A more generalized implementation that mounts an `` on a `` to speed up generation of 2-D content floating in space. Acts as a geometry.
726 |
727 | ### Props
728 |
729 | Inherits from `` and `` and adds
730 | `ppm`: The pixels-per-meter (roughly DPI x 38) to define detail level of your sign.
731 |
732 | **Note** An even higher-level implementation that smushes the node props in is available as ``
733 |
734 | ## ARCenteredSKLabel
735 |
736 | Creates a text label with horizontal and vertical centering.
737 |
738 | ### Props
739 |
740 | Other props inherited from ``
741 |
742 | ### Example
743 |
744 | ```jsx
745 |
746 |
747 |
748 |
749 | ```
750 |
751 | # Enhanced Geometries
752 |
753 | ## Colored Geometries
754 |
755 | These components apply a `color` prop to the diffuse property of all sides of the geometry.
756 |
757 | - ARColoredBox
758 | - ARColoredCapsule
759 | - ARColoredCone
760 | - ARColoredCapsule
761 | - ARColoredPlane
762 | - ARColoredPyramid
763 | - ARColoredShape
764 | - ARColoredSphere
765 | - ARColoredText
766 | - ARColoredTorus
767 | - ARColoredTube
768 |
769 | ## Textured Geometries
770 |
771 | These components apply a `path` prop containing a path to a locally saved texture to all sides of the geometry.
772 |
773 | - ARTexturedBox
774 | - ARTexturedCapsule
775 | - ARTexturedCone
776 | - ARTexturedCapsule
777 | - ARTexturedPlane
778 | - ARTexturedPyramid
779 | - ARTexturedShape
780 | - ARTexturedSphere
781 | - ARTexturedText
782 | - ARTexturedTorus
783 | - ARTexturedTube
784 |
785 | # Enhanced Nodes
786 |
787 | ## Basic Geometry-Node Combinations
788 |
789 | The following components smush the properties of the node with the properties of the geometry. Materials can be applied as children.
790 |
791 | - ARBoxNode
792 | - ARCapsuleNode
793 | - ARConeNode
794 | - ARCapsuleNode
795 | - ARPlaneNode
796 | - ARPyramidNode
797 | - ARShapeNode
798 | - ARSphereNode
799 | - ARTextNode
800 | - ARTorusNode
801 | - ARTubeNode
802 | - ARSignNode
803 | - ARPlaneSceneNode
804 |
805 | ## Colored Geometry-Node Combinations
806 |
807 | The following smush the properties of the node together with the properties of the geometry and add a prop `color` to trigger the diffuse color of the geometry across all surfaces. No material components need to be added.
808 |
809 | - ARColoredBoxNode
810 | - ARColoredCapsuleNode
811 | - ARColoredConeNode
812 | - ARColoredCapsuleNode
813 | - ARColoredPlaneNode
814 | - ARColoredPyramidNode
815 | - ARColoredShapeNode
816 | - ARColoredSphereNode
817 | - ARColoredTextNode
818 | - ARColoredTorusNode
819 | - ARColoredTubeNode
820 |
821 | ## Textured Geometry-Node Combinations
822 |
823 | The following components smush the props of the node and the geometry but allo add a prop `path` to a path texture to be used as the diffuse material. No material components need to be added
824 |
825 | - ARTexturedBoxNode
826 | - ARTexturedCapsuleNode
827 | - ARTexturedConeNode
828 | - ARTexturedCapsuleNode
829 | - ARTexturedPlaneNode
830 | - ARTexturedPyramidNode
831 | - ARTexturedShapeNode
832 | - ARTexturedSphereNode
833 | - ARTexturedTextNode
834 | - ARTexturedTorusNode
835 | - ARTexturedTubeNode
836 |
837 | ## ARMeNode
838 |
839 | Component that represents current user position. Implements the details of a `` so you don't have to.
840 |
841 | # Enhanced Materials
842 |
843 | ## ARColor
844 |
845 | Higher-order component to apply a `color` prop as the material to the geometry you are attaching to.
846 |
847 | ```jsx
848 |
849 |
850 |
851 | ```
852 |
853 | If prop `index` is specified, the color is applied only to that face of the geometry.
854 |
855 | ```jsx
856 |
857 |
858 |
859 |
860 |
861 |
862 |
863 |
864 | ```
865 |
866 | ## ARTexture
867 |
868 | Higher-order component to apply a `path` prop as the path to the texture image for the geometry you are attaching to.
869 |
870 | ```jsx
871 |
872 |
873 |
874 | ```
875 |
876 | If prop `index` is specified, the texture is applied only to that face of the geometry.
877 |
878 | ```jsx
879 |
880 |
881 |
882 |
883 |
884 |
885 |
886 |
887 | ```
888 |
889 | # Enhanced Context Providers
890 |
891 | ## ARNoSession
892 |
893 | Component whose children are displayed when the AR session is not spun up yet. Use for placeholder views.
894 |
895 | ## ARIsSession
896 |
897 | Component whose chidren are displayed when the AR sesison is loaded
898 |
899 | ## ARNoTracking
900 |
901 | Component that shows children when you have no planes or images are detected. Requires `` ancestor in tree
902 |
903 | ## ARIsTracking
904 |
905 | Component that shows only when at least one plane or image detecrted. Requires `` ancestor in tree
906 |
907 | # App.js sample
908 |
909 | ```javascript
910 | import React, { Component } from "react";
911 | import {
912 | ARTouchableMonoView,
913 | ARNode,
914 | ARBox,
915 | ARMaterial,
916 | ARMaterials,
917 | ARMaterialProperty,
918 | ARText,
919 | ARSessionProvider
920 | } from "react-reality";
921 | export default class ARTest extends Component {
922 | state = {
923 | showPreview: true,
924 | fatColor: "blue",
925 | tallColor: "purple"
926 | };
927 | render() {
928 | return (
929 |
930 |
931 | {
934 | this.setState({ fatColor: "green" });
935 | }}
936 | onPressOut={() => {
937 | this.setState({ fatColor: "blue" });
938 | }}
939 | >
940 |
941 |
942 |
943 |
944 |
945 | {
949 | this.setState(({ tallColor }) => {
950 | return {
951 | tallColor: tallColor == "yellow" ? "purple" : "yellow"
952 | };
953 | });
954 | }}
955 | >
956 |
957 |
958 |
962 |
963 |
964 |
968 |
969 |
970 |
971 |
972 |
973 |
974 |
975 |
976 |
977 |
978 |
979 |
980 |
981 |
982 |
983 |
984 |
985 |
986 |
987 |
988 |
989 | );
990 | }
991 | }
992 | ```
993 |
994 | # Credit-Where-Credit-Is-Due
995 |
996 | The idea for this package was as a Swift port of [react-native-arkit](https://github.com/react-native-ar/react-native-arkit), a cool project written in Objective-C, which is not a cool language. Major props to @macrozone for a heck of a lot of work.
997 |
--------------------------------------------------------------------------------
/RNSwiftBridge.js:
--------------------------------------------------------------------------------
1 | import { PropTypes } from "prop-types";
2 | import React, { Component } from "react";
3 | import {
4 | NativeModules,
5 | NativeEventEmitter,
6 | requireNativeComponent,
7 | ViewPropTypes
8 | } from "react-native";
9 | //#region Code for object ARMonoViewManager
10 | const NativeARMonoViewManager = NativeModules.ARMonoViewManager;
11 | const doTap = async (x, y) => {
12 | return await NativeARMonoViewManager.doTap(x, y);
13 | };
14 | //#endregion
15 | const NativeARMonoView = requireNativeComponent("ARMonoView", ARMonoView);
16 | class ARMonoView extends Component {
17 | render() {
18 | return ;
19 | }
20 | }
21 | ARMonoView.propTypes = {
22 | preview: PropTypes.bool,
23 | debugMode: PropTypes.bool,
24 | ...ViewPropTypes
25 | };
26 | const NativeARPrimaryView = requireNativeComponent(
27 | "ARPrimaryView",
28 | ARPrimaryView
29 | );
30 | class ARPrimaryView extends Component {
31 | render() {
32 | return ;
33 | }
34 | }
35 | ARPrimaryView.propTypes = {
36 | interPupilaryDistance: PropTypes.number,
37 | holoOffsetY: PropTypes.number,
38 | holoOffsetZ: PropTypes.number,
39 | holoOffsetX: PropTypes.number,
40 | fieldOfView: PropTypes.number,
41 | ...ViewPropTypes
42 | };
43 | const NativeARProjectedView = requireNativeComponent(
44 | "ARProjectedView",
45 | ARProjectedView
46 | );
47 | class ARProjectedView extends Component {
48 | render() {
49 | return ;
50 | }
51 | }
52 | ARProjectedView.propTypes = {
53 | parentNode: PropTypes.string,
54 | ...ViewPropTypes
55 | };
56 | //#region Code for object ARSceneManager
57 | const NativeARSceneManager = NativeModules.ARSceneManager;
58 | const addNode = async (node, parentID) => {
59 | return await NativeARSceneManager.addNode(node, parentID);
60 | };
61 | const removeNode = async id => {
62 | return await NativeARSceneManager.removeNode(id);
63 | };
64 | const updateNode = async (forNode, newProps) => {
65 | return await NativeARSceneManager.updateNode(forNode, newProps);
66 | };
67 | const setBox = async (g, forNode) => {
68 | return await NativeARSceneManager.setBox(g, forNode);
69 | };
70 | const setCapsule = async (g, forNode) => {
71 | return await NativeARSceneManager.setCapsule(g, forNode);
72 | };
73 | const setCone = async (g, forNode) => {
74 | return await NativeARSceneManager.setCone(g, forNode);
75 | };
76 | const setCylinder = async (g, forNode) => {
77 | return await NativeARSceneManager.setCylinder(g, forNode);
78 | };
79 | const setPlane = async (g, forNode) => {
80 | return await NativeARSceneManager.setPlane(g, forNode);
81 | };
82 | const setPyramid = async (g, forNode) => {
83 | return await NativeARSceneManager.setPyramid(g, forNode);
84 | };
85 | const setSphere = async (g, forNode) => {
86 | return await NativeARSceneManager.setSphere(g, forNode);
87 | };
88 | const setText = async (g, forNode) => {
89 | return await NativeARSceneManager.setText(g, forNode);
90 | };
91 | const setTorus = async (g, forNode) => {
92 | return await NativeARSceneManager.setTorus(g, forNode);
93 | };
94 | const setTube = async (g, forNode) => {
95 | return await NativeARSceneManager.setTube(g, forNode);
96 | };
97 | const setShape = async (g, forNode) => {
98 | return await NativeARSceneManager.setShape(g, forNode);
99 | };
100 | const setGeometry = async (geometry, forNode) => {
101 | return await NativeARSceneManager.setGeometry(geometry, forNode);
102 | };
103 | const setLight = async (light, forNode) => {
104 | return await NativeARSceneManager.setLight(light, forNode);
105 | };
106 | const removeLight = async forNode => {
107 | return await NativeARSceneManager.removeLight(forNode);
108 | };
109 | const setMaterial = async (material, forNode, atPosition) => {
110 | return await NativeARSceneManager.setMaterial(material, forNode, atPosition);
111 | };
112 | const setMaterialProperty = async (
113 | json,
114 | propertyName,
115 | forMaterialAtPosition,
116 | forNode
117 | ) => {
118 | return await NativeARSceneManager.setMaterialProperty(
119 | json,
120 | propertyName,
121 | forMaterialAtPosition,
122 | forNode
123 | );
124 | };
125 | const removeGeometry = async forNode => {
126 | return await NativeARSceneManager.removeGeometry(forNode);
127 | };
128 | const removeMaterial = async (forNode, atPosition) => {
129 | return await NativeARSceneManager.removeMaterial(forNode, atPosition);
130 | };
131 | const setScene = async (forNode, sourcePath) => {
132 | return await NativeARSceneManager.setScene(forNode, sourcePath);
133 | };
134 | const setModel = async (forNode, sourcePath) => {
135 | return await NativeARSceneManager.setModel(forNode, sourcePath);
136 | };
137 | const addSKSceneReference = async scene => {
138 | return await NativeARSceneManager.addSKSceneReference(scene);
139 | };
140 | const addSKSceneByReference = async (
141 | sceneName,
142 | forNode,
143 | atPosition,
144 | withType
145 | ) => {
146 | return await NativeARSceneManager.addSKSceneByReference(
147 | sceneName,
148 | forNode,
149 | atPosition,
150 | withType
151 | );
152 | };
153 | const addSKScene = async (scene, forNode, atPosition, withType) => {
154 | return await NativeARSceneManager.addSKScene(
155 | scene,
156 | forNode,
157 | atPosition,
158 | withType
159 | );
160 | };
161 | const updateSKScene = async (scene, forNode, atPosition, withType) => {
162 | return await NativeARSceneManager.updateSKScene(
163 | scene,
164 | forNode,
165 | atPosition,
166 | withType
167 | );
168 | };
169 | const setSKLabelNode = async (node, toParent) => {
170 | return await NativeARSceneManager.setSKLabelNode(node, toParent);
171 | };
172 | const updateSKLabelNode = async json => {
173 | return await NativeARSceneManager.updateSKLabelNode(json);
174 | };
175 | const setSKVideoNode = async (node, toParent) => {
176 | return await NativeARSceneManager.setSKVideoNode(node, toParent);
177 | };
178 | const updateSKVideoNode = async json => {
179 | return await NativeARSceneManager.updateSKVideoNode(json);
180 | };
181 | const setSKNode = async (node, toParent) => {
182 | return await NativeARSceneManager.setSKNode(node, toParent);
183 | };
184 | const removeSKNode = async name => {
185 | return await NativeARSceneManager.removeSKNode(name);
186 | };
187 | const removeSKScene = async (forNode, atPosition, withType) => {
188 | return await NativeARSceneManager.removeSKScene(
189 | forNode,
190 | atPosition,
191 | withType
192 | );
193 | };
194 | const addSKLabelNode = async (node, toParent) => {
195 | return await NativeARSceneManager.addSKLabelNode(node, toParent);
196 | };
197 | const addSKNode = async (node, toParent) => {
198 | return await NativeARSceneManager.addSKNode(node, toParent);
199 | };
200 | const clear = async () => {
201 | return await NativeARSceneManager.clear();
202 | };
203 | const resume = async () => {
204 | return await NativeARSceneManager.resume();
205 | };
206 | const pause = async () => {
207 | return await NativeARSceneManager.pause();
208 | };
209 | const setAnimation = async (seconds, type) => {
210 | return await NativeARSceneManager.setAnimation(seconds, type);
211 | };
212 | const setAnimationDuration = async seconds => {
213 | return await NativeARSceneManager.setAnimationDuration(seconds);
214 | };
215 | const setAnimationType = async type => {
216 | return await NativeARSceneManager.setAnimationType(type);
217 | };
218 | const setPlaneDetection = async detectPlanes => {
219 | return await NativeARSceneManager.setPlaneDetection(detectPlanes);
220 | };
221 | const getAnchors = async () => {
222 | return await NativeARSceneManager.getAnchors();
223 | };
224 | const removeAnchor = async id => {
225 | return await NativeARSceneManager.removeAnchor(id);
226 | };
227 | const addRecognizerImage = async (url, name, width) => {
228 | return await NativeARSceneManager.addRecognizerImage(url, name, width);
229 | };
230 | const removeRecognizerImage = async name => {
231 | return await NativeARSceneManager.removeRecognizerImage(name);
232 | };
233 | const setImageDetection = async doDetect => {
234 | return await NativeARSceneManager.setImageDetection(doDetect);
235 | };
236 | const projectNode = async nodeID => {
237 | return await NativeARSceneManager.projectNode(nodeID);
238 | };
239 | const projectWorldPoint = async v => {
240 | return await NativeARSceneManager.projectWorldPoint(v);
241 | };
242 | const setPOVSensitivity = async newSensitivity => {
243 | return await NativeARSceneManager.setPOVSensitivity(newSensitivity);
244 | };
245 | const setPOVOrientationSensitivity = async newSensitivity => {
246 | return await NativeARSceneManager.setPOVOrientationSensitivity(
247 | newSensitivity
248 | );
249 | };
250 | const getPOV = async () => {
251 | return await NativeARSceneManager.getPOV();
252 | };
253 | const setWorldTracking = async trackingMode => {
254 | return await NativeARSceneManager.setWorldTracking(trackingMode);
255 | };
256 | const hitTestPlane = async (point, detectType) => {
257 | return await NativeARSceneManager.hitTestPlane(point, detectType);
258 | };
259 | //#endregion
260 | //#region events for object ARSceneManager
261 | var _getNativeARSceneManagerEventEmitter = null;
262 | const getNativeARSceneManagerEventEmitter = () => {
263 | if (!_getNativeARSceneManagerEventEmitter)
264 | _getNativeARSceneManagerEventEmitter = new NativeEventEmitter(
265 | NativeARSceneManager
266 | );
267 | return _getNativeARSceneManagerEventEmitter;
268 | };
269 | const subscribeToARSessionError = cb => {
270 | return getNativeARSceneManagerEventEmitter().addListener(
271 | "ARSessionError",
272 | cb
273 | );
274 | };
275 | const subscribeToAREvent = cb => {
276 | return getNativeARSceneManagerEventEmitter().addListener("AREvent", cb);
277 | };
278 | const subscribeToARPlaneEvent = cb => {
279 | return getNativeARSceneManagerEventEmitter().addListener("ARPlaneEvent", cb);
280 | };
281 | const subscribeToARImageEvent = cb => {
282 | return getNativeARSceneManagerEventEmitter().addListener("ARImageEvent", cb);
283 | };
284 | const subscribeToARCameraState = cb => {
285 | return getNativeARSceneManagerEventEmitter().addListener("ARCameraState", cb);
286 | };
287 | const subscribeToARPositionChange = cb => {
288 | return getNativeARSceneManagerEventEmitter().addListener(
289 | "ARPositionChange",
290 | cb
291 | );
292 | };
293 | //#endregion
294 | const NativeARSecondaryView = requireNativeComponent(
295 | "ARSecondaryView",
296 | ARSecondaryView
297 | );
298 | class ARSecondaryView extends Component {
299 | render() {
300 | return ;
301 | }
302 | }
303 | ARSecondaryView.propTypes = {
304 | ...ViewPropTypes
305 | };
306 | //#region Event marshalling object
307 | const RNSEvents = {
308 | ARSessionError: subscribeToARSessionError,
309 | AREvent: subscribeToAREvent,
310 | ARPlaneEvent: subscribeToARPlaneEvent,
311 | ARImageEvent: subscribeToARImageEvent,
312 | ARCameraState: subscribeToARCameraState,
313 | ARPositionChange: subscribeToARPositionChange
314 | };
315 | //#endregion
316 | //#region Exports
317 | export {
318 | doTap,
319 | ARMonoView,
320 | ARPrimaryView,
321 | ARProjectedView,
322 | addNode,
323 | removeNode,
324 | updateNode,
325 | setBox,
326 | setCapsule,
327 | setCone,
328 | setCylinder,
329 | setPlane,
330 | setPyramid,
331 | setSphere,
332 | setText,
333 | setTorus,
334 | setTube,
335 | setShape,
336 | setGeometry,
337 | setLight,
338 | removeLight,
339 | setMaterial,
340 | setMaterialProperty,
341 | removeGeometry,
342 | removeMaterial,
343 | setScene,
344 | setModel,
345 | addSKSceneReference,
346 | addSKSceneByReference,
347 | addSKScene,
348 | updateSKScene,
349 | setSKLabelNode,
350 | updateSKLabelNode,
351 | setSKVideoNode,
352 | updateSKVideoNode,
353 | setSKNode,
354 | removeSKNode,
355 | removeSKScene,
356 | addSKLabelNode,
357 | addSKNode,
358 | clear,
359 | resume,
360 | pause,
361 | setAnimation,
362 | setAnimationDuration,
363 | setAnimationType,
364 | setPlaneDetection,
365 | getAnchors,
366 | removeAnchor,
367 | addRecognizerImage,
368 | removeRecognizerImage,
369 | setImageDetection,
370 | projectNode,
371 | projectWorldPoint,
372 | setPOVSensitivity,
373 | setPOVOrientationSensitivity,
374 | getPOV,
375 | setWorldTracking,
376 | hitTestPlane,
377 | subscribeToARSessionError,
378 | subscribeToAREvent,
379 | subscribeToARPlaneEvent,
380 | subscribeToARImageEvent,
381 | subscribeToARCameraState,
382 | subscribeToARPositionChange,
383 | ARSecondaryView,
384 | RNSEvents
385 | };
386 | //#endregion
387 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-cayman
--------------------------------------------------------------------------------
/components/ARBox.js:
--------------------------------------------------------------------------------
1 | import PropTypes from "prop-types";
2 | import ARGeometry from "./ARGeometry";
3 | import { setBox } from "../RNSwiftBridge";
4 | export default ARGeometry(
5 | setBox,
6 | {
7 | width: PropTypes.number,
8 | height: PropTypes.number,
9 | length: PropTypes.number,
10 | chamfer: PropTypes.number
11 | },
12 | 6,
13 | {
14 | height: 1,
15 | width: 1,
16 | length: 1,
17 | chamfer: 0
18 | }
19 | );
20 |
--------------------------------------------------------------------------------
/components/ARCapsule.js:
--------------------------------------------------------------------------------
1 | import PropTypes from "prop-types";
2 | import ARGeometry from "./ARGeometry";
3 |
4 | import { setCapsule } from "../RNSwiftBridge";
5 | export default ARGeometry(
6 | setCapsule,
7 | {
8 | capR: PropTypes.number,
9 | height: PropTypes.number
10 | },
11 | 3,
12 | {
13 | capR: 0.5,
14 | height: 1
15 | }
16 | );
17 |
--------------------------------------------------------------------------------
/components/ARCone.js:
--------------------------------------------------------------------------------
1 | import PropTypes from "prop-types";
2 | import ARGeometry from "./ARGeometry";
3 |
4 | import { setCone } from "../RNSwiftBridge";
5 | export default ARGeometry(
6 | setCone,
7 | {
8 | topR: PropTypes.number,
9 | bottomR: PropTypes.number,
10 | height: PropTypes.number
11 | },
12 | ({ topR, bottomR }) => {
13 | if (topR > 0 && bottomR > 0) {
14 | return 3;
15 | }
16 | return 2;
17 | },
18 | {
19 | topR: 0,
20 | bottomR: 0.5,
21 | height: 1
22 | }
23 | );
24 |
--------------------------------------------------------------------------------
/components/ARCylinder.js:
--------------------------------------------------------------------------------
1 | import PropTypes from "prop-types";
2 | import ARGeometry from "./ARGeometry";
3 | import { setCylinder } from "../RNSwiftBridge";
4 | export default ARGeometry(
5 | setCylinder,
6 | {
7 | radius: PropTypes.number,
8 | height: PropTypes.number
9 | },
10 | 2,
11 | {
12 | radius: 0.5,
13 | height: 1
14 | }
15 | );
16 |
--------------------------------------------------------------------------------
/components/ARGeometry.js:
--------------------------------------------------------------------------------
1 | import React, { Component, createContext } from "react";
2 | import PropTypes from "prop-types";
3 | import filter from "lodash/filter";
4 | import pickBy from "lodash/pickBy";
5 | import { adopt } from "react-adopt";
6 | import { removeGeometry } from "../RNSwiftBridge";
7 | import { ARNodeConsumer } from "./ARNode";
8 | import { ARAnimatedConsumer } from "../ARAnimatedProvider";
9 | const { Provider, Consumer: ARGeometryConsumer } = createContext({});
10 |
11 | const ARGeometry = (mountFunc, geomProps, numSides, defaults) => {
12 | const ARBaseGeometry = class extends Component {
13 | state = {
14 | updateState: "doMount" // Finite state: shouldMount, doMount, Mounting, doNext, do, doing, done
15 | };
16 | constructor(props) {
17 | super(props);
18 | this.state.providerValue = {
19 | numSides: typeof numSides == "function" ? numSides(props) : numSides
20 | };
21 | }
22 | async nativeUpdate() {
23 | if (this.state.updateState == "doMount") {
24 | if (!this.props.parentNode)
25 | throw new Error("Cannot mount a Geometry without a parent Node");
26 | this.setState({ updateState: "Mounting" });
27 | try {
28 | if (this.props.willNativeUpdate) await this.props.willNativeUpdate();
29 | await mountFunc(this.state.geomProps, this.props.parentNode);
30 | if (this.props.didNativeUpdate) await this.props.didNativeUpdate();
31 | this.setState(({ updateState }) => {
32 | return { updateState: updateState == "doNext" ? "do" : "done" };
33 | });
34 | } catch (e) {
35 | this.setState({ updateState: "doMount" });
36 | console.log("I got an error", e);
37 | }
38 | } else if (this.state.updateState == "do") {
39 | if (!this.props.parentNode)
40 | throw new Error("Cannot mount a Geometry without a parent Node");
41 | this.setState({ updateState: "doing" });
42 | try {
43 | if (this.props.willNativeUpdate) await this.props.willNativeUpdate();
44 | await mountFunc(this.state.geomProps, this.props.parentNode);
45 | if (this.props.didNativeUpdate) await this.props.didNativeUpdate();
46 | //DO something
47 | this.setState(({ updateState }) => {
48 | return { updateState: updateState == "doNext" ? "do" : "done" };
49 | });
50 | } catch (e) {
51 | console.log("I got an error", e);
52 | this.setState({ updateState: "doMount" });
53 | }
54 | }
55 | }
56 | componentWillUnmount() {
57 | if (!this.props.parentNode)
58 | throw new Error("Cannot mount a Geometry without a parent Node");
59 | async () => {
60 | try {
61 | await removeGeometry(this.props.parentNode);
62 | } catch (e) {}
63 | };
64 | }
65 | render() {
66 | if (!this.props.children) return null;
67 | if (
68 | ["shouldMount", "doMount", "Mounting", "doing"].indexOf(
69 | this.state.updateState
70 | ) > -1
71 | )
72 | return null;
73 | return (
74 |
75 | {this.props.children}
76 |
77 | );
78 | }
79 | componentDidMount() {
80 | this.nativeUpdate();
81 | }
82 | componentDidUpdate() {
83 | this.nativeUpdate();
84 | }
85 | static getDerivedStateFromProps(nextProps, prevState) {
86 | var ret = prevState;
87 | if (propDiff(prevState.geomProps, nextProps)) {
88 | if (["shouldMount", "doMount"].indexOf(ret.updateState) == -1)
89 | ret.updateState =
90 | ["doing", "Mounting"].indexOf(prevState.updateState) > -1
91 | ? "doNext"
92 | : "do";
93 | ret.geomProps = propFilter(nextProps);
94 | }
95 | return ret;
96 | }
97 | };
98 | const propFilter = props => {
99 | return pickBy(props, (v, k) => {
100 | return geomPropKeys.indexOf(k) > -1;
101 | });
102 | };
103 | const propDiff = (a, b) => {
104 | if (a === b) return false;
105 | if (a & !b || !a & b) return true;
106 | const af = propFilter(a);
107 | const bf = propFilter(b);
108 |
109 | const afk = Object.keys(af);
110 | const bfk = Object.keys(bf);
111 | if (afk.length != bfk.length) return true;
112 | if (
113 | afk.filter(k => {
114 | return bfk.indexOf(k) === -1;
115 | }).length
116 | )
117 | return true;
118 | if (
119 | afk.filter(k => {
120 | return bf[k] != af[k];
121 | }).length
122 | )
123 | return true;
124 | };
125 | ARBaseGeometry.propTypes = {
126 | ...geomProps,
127 | parentNode: PropTypes.string,
128 | willNativeUpdate: PropTypes.func,
129 | didNativeUpdate: PropTypes.func
130 | };
131 | if (defaults) {
132 | ARBaseGeometry.defaultProps = defaults;
133 | }
134 | const geomPropKeys = Object.keys(ARBaseGeometry.propTypes);
135 | const Adoptee = adopt({
136 | animated: ,
137 | node:
138 | });
139 | const ARGeometry = props => {
140 | return (
141 |
142 | {({
143 | animated: { willNativeUpdate, didNativeUpdate },
144 | node: { nodeID }
145 | }) => {
146 | return (
147 |
153 | );
154 | }}
155 |
156 | );
157 | };
158 | return ARGeometry;
159 | };
160 | export { ARGeometry, ARGeometryConsumer, Provider as ARGeometryProvider };
161 | export default ARGeometry;
162 |
--------------------------------------------------------------------------------
/components/ARLight.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import PropTypes from "prop-types";
3 | import { adopt } from "react-adopt";
4 | import { processColor } from "react-native";
5 | import pickBy from "lodash/pickBy";
6 | import includes from "lodash/includes";
7 | import { ARNodeConsumer } from "./ARNode";
8 | import { ARAnimatedConsumer } from "../ARAnimatedProvider";
9 | import { setLight, removeLight } from "../RNSwiftBridge";
10 | import { ARGeometryProvider } from "./ARGeometry";
11 | class ARBaseLight extends Component {
12 | state = { updateState: "doMount" };
13 | render() {
14 | if (!this.props.children) return null;
15 | if (
16 | ["shouldMount", "doMount", "Mounting", "doing"].indexOf(
17 | this.state.updateState
18 | ) > -1
19 | )
20 | return null;
21 | //Setting no-op geometryprovider so if someone adds materials underneath, they get ignored.
22 | return (
23 |
24 | {this.props.children}
25 |
26 | );
27 | }
28 | componentWillUnmount() {
29 | if (!this.props.parentNode)
30 | throw new Error("Cannot mount a Geometry without a parent Node");
31 | async () => {
32 | try {
33 | await removeLight(this.props.parentNode);
34 | } catch (e) {}
35 | };
36 | }
37 | componentDidMount() {
38 | this.nativeUpdate();
39 | }
40 | componentDidUpdate() {
41 | this.nativeUpdate();
42 | }
43 | static getDerivedStateFromProps(nextProps, prevState) {
44 | var ret = prevState;
45 | if (propDiff(prevState.lightProps, nextProps)) {
46 | if (["shouldMount", "doMount"].indexOf(ret.updateState) == -1) {
47 | ret.updateState =
48 | ["doing", "Mounting"].indexOf(prevState.updateState) > -1
49 | ? "doNext"
50 | : "do";
51 | }
52 | ret.lightProps = propFilter(nextProps);
53 | }
54 | return ret;
55 | }
56 | async nativeUpdate() {
57 | if (this.state.updateState == "doMount") {
58 | if (!this.props.parentNode)
59 | throw new Error("Cannot mount a Geometry without a parent Node");
60 | this.setState({ updateState: "Mounting" });
61 | try {
62 | if (this.props.willNativeUpdate) await this.props.willNativeUpdate();
63 | await setLight(this.state.lightProps, this.props.parentNode);
64 | if (this.props.didNativeUpdate) await this.props.didNativeUpdate();
65 | this.setState(({ updateState }) => {
66 | return { updateState: updateState == "doNext" ? "do" : "done" };
67 | });
68 | } catch (e) {
69 | this.setState({ updateState: "doMount" });
70 | console.log("I got an error", e);
71 | }
72 | } else if (this.state.updateState == "do") {
73 | if (!this.props.parentNode)
74 | throw new Error("Cannot mount a Geometry without a parent Node");
75 | this.setState({ updateState: "doing" });
76 | try {
77 | if (this.props.willNativeUpdate) await this.props.willNativeUpdate();
78 | await setLight(this.state.lightProps, this.props.parentNode);
79 | if (this.props.didNativeUpdate) await this.props.didNativeUpdate();
80 | //DO something
81 | this.setState(({ updateState }) => {
82 | return { updateState: updateState == "doNext" ? "do" : "done" };
83 | });
84 | } catch (e) {
85 | console.log("I got an error", e);
86 | this.setState({ updateState: "doMount" });
87 | }
88 | }
89 | }
90 | }
91 | const Adoptee = adopt({
92 | animated: ,
93 | node:
94 | });
95 | const ARLight = props => {
96 | return (
97 |
98 | {({
99 | animated: { willNativeUpdate, didNativeUpdate },
100 | node: { nodeID }
101 | }) => {
102 | return (
103 |
109 | );
110 | }}
111 |
112 | );
113 | };
114 | const propFilter = props => {
115 | const temp = pickBy(
116 | props,
117 | (v, k) =>
118 | materialPropertyPropTypeKeys.indexOf(k) > -1 &&
119 | !includes(
120 | ["updateMaterial", "id", "willNativeUpdate", "didNativeUpdate"],
121 | k
122 | )
123 | );
124 | if (typeof temp.color == "string") temp.color = processColor(temp.color);
125 | return temp;
126 | };
127 | const propDiff = (a, b) => {
128 | if (a === b) return false;
129 | if (a & !b || !a & b) return true;
130 | const af = propFilter(a);
131 | const bf = propFilter(b);
132 |
133 | const afk = Object.keys(af);
134 | const bfk = Object.keys(bf);
135 | if (afk.length != bfk.length) return true;
136 | if (
137 | afk.filter(k => {
138 | return bfk.indexOf(k) === -1;
139 | }).length
140 | )
141 | return true;
142 | if (
143 | afk.filter(k => {
144 | return bf[k] != af[k];
145 | }).length
146 | )
147 | return true;
148 | };
149 |
150 | export default ARLight;
151 |
--------------------------------------------------------------------------------
/components/ARMaterial.js:
--------------------------------------------------------------------------------
1 | import React, { Component, createContext } from "react";
2 | import { processColor } from "react-native";
3 | import { adopt } from "react-adopt";
4 | import {
5 | setMaterial,
6 | setMaterialProperty,
7 | removeMaterial
8 | } from "../RNSwiftBridge";
9 | import PropTypes from "prop-types";
10 | import {
11 | blendMode,
12 | lightingModel,
13 | shaders,
14 | colorBufferWriteMask,
15 | fillMode
16 | } from "./propTypes";
17 | import pickBy from "lodash/pickBy";
18 | import { ARNodeConsumer } from "./ARNode";
19 | import { ARAnimatedConsumer } from "../ARAnimatedProvider";
20 | const { Provider, Consumer: ARMaterialConsumer } = createContext({});
21 | class ARBaseMaterial extends Component {
22 | state = {
23 | updateState: "doMount" // States: doMount, Mounting, (doNext, doing,) done
24 | };
25 | constructor(props) {
26 | super(props);
27 | this.state.materialPropertyProps = {
28 | updateMaterial: this.updateMaterial.bind(this),
29 | parentNode: this.props.parentNode,
30 | index: this.props.index
31 | };
32 | }
33 | async nativeUpdate() {
34 | if (this.state.updateState == "doMount") {
35 | const filteredProps = pickBy(
36 | this.props,
37 | (v, k) => materialPropKeys.indexOf(k) > -1
38 | );
39 | const index = this.props.index ? this.props.index : 0;
40 | this.setState({ updateState: "Mounting" });
41 | try {
42 | if (this.props.willNativeUpdate) await this.props.willNativeUpdate();
43 | setMaterial(filteredProps, this.props.parentNode, index);
44 | if (this.props.didNativeUpdate) await this.props.didNativeUpdate();
45 | this.setState({ updateState: "done" });
46 | } catch (e) {
47 | this.setState({ updateState: "doMount" });
48 | }
49 | }
50 | }
51 | componentDidMount() {
52 | this.nativeUpdate();
53 | }
54 | componentDidUpdate() {
55 | this.nativeUpdate();
56 | }
57 | async updateMaterial(id, property) {
58 | try {
59 | if (this.props.willNativeUpdate) await this.props.willNativeUpdate();
60 | const filteredProperty = {
61 | ...property,
62 | color:
63 | typeof property.color == "string"
64 | ? processColor(property.color)
65 | : property.color
66 | };
67 | await setMaterialProperty(
68 | filteredProperty,
69 | id,
70 | this.props.index,
71 | this.props.parentNode
72 | );
73 | if (this.props.didNativeUpdate) await this.props.didNativeUpdate();
74 | } catch (e) {
75 | console.log("Uh oh , mp error", e);
76 | }
77 | }
78 | render() {
79 | if (["doMount", "Mounting"].indexOf(this.state.updateState) > -1)
80 | return null;
81 | if (!this.props.children) return null;
82 | return (
83 |
84 | {this.props.children}
85 |
86 | );
87 | }
88 | componentWillUnmount() {
89 | async () => {
90 | try {
91 | removeMaterial(this.props.parentNode, this.props.index);
92 | } catch (e) {}
93 | };
94 | }
95 | }
96 | ARBaseMaterial.propTypes = {
97 | parentNode: PropTypes.string,
98 | index: PropTypes.number,
99 | metalness: PropTypes.number,
100 | roughness: PropTypes.number,
101 | blendMode,
102 | lightingModel,
103 | shaders,
104 | writesToDepthBuffer: PropTypes.bool,
105 | colorBufferWriteMask,
106 | doubleSided: PropTypes.bool,
107 | litPerPixel: PropTypes.bool,
108 | transparency: PropTypes.number,
109 | fillMode,
110 | willNativeUpdate: PropTypes.func,
111 | didNativeUpdate: PropTypes.func
112 | };
113 | const materialPropKeys = Object.keys(ARBaseMaterial.propTypes);
114 | const Adoptee = adopt({
115 | animated: ,
116 | node:
117 | });
118 | const ARMaterial = props => {
119 | return (
120 |
121 | {({
122 | animated: { willNativeUpdate, didNativeUpdate },
123 | node: { nodeID }
124 | }) => {
125 | return (
126 |
132 | );
133 | }}
134 |
135 | );
136 | };
137 | export { ARMaterial, ARMaterialConsumer };
138 | export default ARMaterial;
139 |
--------------------------------------------------------------------------------
/components/ARMaterialProperty.js:
--------------------------------------------------------------------------------
1 | import React, { Component, createContext } from "react";
2 | import PropTypes from "prop-types";
3 | import pickBy from "lodash/pickBy";
4 | import includes from "lodash/includes";
5 | import { adopt } from "react-adopt";
6 | import { ARMaterialConsumer } from "./ARMaterial";
7 | import { ARAnimatedConsumer } from "../ARAnimatedProvider";
8 | const { Provider, Consumer: ARMaterialPropertyConsumer } = createContext({});
9 | class ARBaseMaterialProperty extends Component {
10 | state = {
11 | updateState: "doMount" // valid states: doMount, Mounting, doNext, do, doing, done
12 | };
13 | constructor(props) {
14 | super(props);
15 | this.state.providerValue = {
16 | parentNode: this.props.parentNode,
17 | index: this.props.index,
18 | materialProperty: this.props.id
19 | };
20 | this.state.filteredProps = propFilter(this.props);
21 | }
22 |
23 | render() {
24 | if (!this.props.children) return null;
25 | if (["doMount", "Mounting"].indexOf(this.state.updateState) > -1)
26 | return null;
27 | return (
28 |
29 | {this.props.children}
30 |
31 | );
32 | }
33 | async nativeUpdate() {
34 | if (this.state.updateState == "doMount") {
35 | this.setState({ updateState: "Mounting" });
36 | try {
37 | if (typeof this.props.willNativeUpdate == "function")
38 | await this.props.willNativeUpdate();
39 | await this.props.updateMaterial(
40 | this.props.id,
41 | this.state.filteredProps
42 | );
43 | if (typeof this.props.didNativeUpdate == "function")
44 | await this.props.didNativeUpdate();
45 | this.setState(({ updateState }) => {
46 | return { updateState: updateState == "doNext" ? "do" : "done" };
47 | });
48 | } catch (e) {
49 | console.log("Hit error mounting property", this.state.filteredProps, e);
50 | this.setState({ updateState: "doMount" });
51 | }
52 | }
53 | if (this.state.updateState == "do") {
54 | this.setState({ updateState: "doing" });
55 | try {
56 | if (typeof this.props.willNativeUpdate == "function")
57 | await this.props.willNativeUpdate();
58 | await this.props.updateMaterial(
59 | this.props.id,
60 | this.state.filteredProps
61 | );
62 | if (typeof this.props.didNativeUpdate == "function")
63 | await this.props.didNativeUpdate();
64 | this.setState(({ updateState }) => {
65 | return { updateState: updateState == "doNext" ? "do" : "done" };
66 | });
67 | } catch (e) {
68 | console.log("hit error updating property", e);
69 | this.setState({ updateState: "do" });
70 | }
71 | }
72 | }
73 | componentDidMount() {
74 | this.nativeUpdate();
75 | }
76 | componentDidUpdate() {
77 | this.nativeUpdate();
78 | }
79 | static getDerivedStateFromProps(nextProps, prevState) {
80 | const ret = prevState;
81 | if (propDiff(prevState.filteredProps, nextProps, propFilter)) {
82 | ret.filteredProps = propFilter(nextProps);
83 | if (prevState.updateState != "doMount") {
84 | ret.updateState =
85 | ["doing", "mounting"].indexOf(prevState.updateState) > -1
86 | ? "doNext"
87 | : "do";
88 | }
89 | }
90 | return ret;
91 | }
92 | }
93 | ARBaseMaterialProperty.propTypes = {
94 | updateMaterial: PropTypes.func,
95 | id: PropTypes.string,
96 | path: PropTypes.string,
97 | color: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
98 | intensity: PropTypes.number,
99 | willNativeUpdate: PropTypes.func,
100 | didNativeUpdate: PropTypes.func
101 | };
102 | ARBaseMaterialProperty.defaultProps = {
103 | id: "diffuse"
104 | };
105 | materialPropertyPropTypeKeys = Object.keys(ARBaseMaterialProperty.propTypes);
106 | const Adoptee = adopt({
107 | animated: ,
108 | material:
109 | });
110 | const ARMaterialProperty = props => {
111 | return (
112 |
113 | {({
114 | animated: { willNativeUpdate, didNativeUpdate },
115 | material: { updateMaterial, parentNode, index }
116 | }) => {
117 | return (
118 |
126 | );
127 | }}
128 |
129 | );
130 | };
131 | const propFilter = props => {
132 | return pickBy(
133 | props,
134 | (v, k) =>
135 | materialPropertyPropTypeKeys.indexOf(k) > -1 &&
136 | !includes(
137 | ["updateMaterial", "id", "willNativeUpdate", "didNativeUpdate"],
138 | k
139 | )
140 | );
141 | };
142 | const propDiff = (a, b) => {
143 | if (a === b) return false;
144 | if (a & !b || !a & b) return true;
145 | const af = propFilter(a);
146 | const bf = propFilter(b);
147 |
148 | const afk = Object.keys(af);
149 | const bfk = Object.keys(bf);
150 | if (afk.length != bfk.length) return true;
151 | if (
152 | afk.filter(k => {
153 | return bfk.indexOf(k) === -1;
154 | }).length
155 | )
156 | return true;
157 | if (
158 | afk.filter(k => {
159 | return bf[k] != af[k];
160 | }).length
161 | )
162 | return true;
163 | };
164 | export { ARMaterialProperty, ARMaterialPropertyConsumer };
165 | export default ARMaterialProperty;
166 |
--------------------------------------------------------------------------------
/components/ARMaterials.js:
--------------------------------------------------------------------------------
1 | import React, { Component, Children } from "react";
2 | import PropTypes from "prop-types";
3 | import pickBy from "lodash/pickBy";
4 | import ARMaterial from "./ARMaterial";
5 | import { ARGeometryConsumer } from "./ARGeometry";
6 | const ARMaterials = props => {
7 | if (props.children == null) return null;
8 | return (
9 |
10 | {({ numSides }) => {
11 | var out = [];
12 | if (!numSides) return null;
13 | for (var s = 0; s < numSides; s++) {
14 | var c = null;
15 | c = Children.map(props.children, child => {
16 | return React.cloneElement(child);
17 | });
18 | out.push();
19 | }
20 | return out;
21 | }}
22 |
23 | );
24 | };
25 | ARMaterials.propTypes = pickBy(
26 | ARMaterial.propTypes,
27 | (v, k) => ["index"].indexOf(k) === -1
28 | );
29 | export default ARMaterials;
30 |
--------------------------------------------------------------------------------
/components/ARModel.js:
--------------------------------------------------------------------------------
1 | import PropTypes from "prop-types";
2 | import ARGeometry from "./ARGeometry";
3 | import { setModel } from "../RNSwiftBridge";
4 | export default ARGeometry(
5 | async ({ path }, nodeID) => {
6 | return await setModel(nodeID, path);
7 | },
8 | {
9 | path: PropTypes.string
10 | },
11 | 0
12 | );
13 |
--------------------------------------------------------------------------------
/components/ARNode.js:
--------------------------------------------------------------------------------
1 | import React, { Component, createContext } from "react";
2 | import PropTypes from "prop-types";
3 | import pickBy from "lodash/pickBy";
4 | import { adopt } from "react-adopt";
5 | import { ARSessionConsumer } from "../ARSessionProvider";
6 | import { ARAnimatedConsumer } from "../ARAnimatedProvider";
7 | import { ARTouchConsumer } from "../ARTouchProvider";
8 | import {
9 | eulerAngles,
10 | orientation,
11 | position,
12 | rotation,
13 | scale,
14 | opacity,
15 | renderingOrder
16 | } from "./propTypes";
17 | import UUID from "uuid/v4";
18 | import { addNode, removeNode, updateNode } from "../RNSwiftBridge";
19 | const { Provider, Consumer: ARNodeConsumer } = createContext({});
20 | //#region BaseNode
21 | class ARBaseNode extends Component {
22 | state = {
23 | updateState: "shouldmount", // Valid values: "shouldmount", "domount", "mounting", "donext", "do", "doing", "done"
24 | identifier: null
25 | };
26 | constructor(props) {
27 | super(props);
28 | this.state.identifier = props.id ? props.id : UUID();
29 | this.state.providerValue = { nodeID: this.state.identifier };
30 | }
31 | componentDidMount() {
32 | this.nativeUpdate();
33 | if (this.props.registerNode)
34 | this.props.registerNode(this.state.identifier, this);
35 | }
36 | render() {
37 | if (!this.props.children) return null;
38 | if (
39 | ["shouldmount", "domount", "mounting"].indexOf(this.state.updateState) >
40 | -1
41 | ) {
42 | return null;
43 | }
44 | return (
45 |
46 | {this.props.children}
47 |
48 | );
49 | }
50 | static getDerivedStateFromProps(nextProps, prevState) {
51 | var ret = prevState;
52 | if (propDiff(prevState.nodeProps, nextProps, filterObj)) {
53 | //Change to node
54 | if (prevState.updateState != "donext") {
55 | ret.updateState =
56 | prevState.updateState == "shouldmount"
57 | ? "domount"
58 | : ["mounting", "doing"].indexOf(prevState.updateState) > -1
59 | ? "donext"
60 | : "do";
61 | }
62 | ret.nodeProps = filterObj(nextProps);
63 | }
64 | return ret;
65 | }
66 | componentDidUpdate() {
67 | this.nativeUpdate();
68 | }
69 | async nativeUpdate() {
70 | if (this.state.updateState == "domount") {
71 | this.setState({ updateState: "mounting" });
72 | try {
73 | const parentNode = this.props.parentNode ? this.props.parentNode : "";
74 | const np = { ...this.state.nodeProps, id: this.state.identifier };
75 | if (typeof this.props.willNativeUpdate == "function")
76 | await this.props.willNativeUpdate();
77 | await addNode(np, parentNode);
78 | if (typeof this.props.didNativeUpdate == "function")
79 | await this.props.didNativeUpdate();
80 | this.setState(({ updateState }) => {
81 | return { updateState: updateState == "donext" ? "do" : "done" };
82 | });
83 | } catch (e) {
84 | this.setState({ updateState: "domount" });
85 | }
86 | } else if (this.state.updateState == "do") {
87 | this.setState({ updateState: "doing" });
88 | try {
89 | if (typeof this.props.willNativeUpdate == "function")
90 | await this.props.willNativeUpdate();
91 | await updateNode(this.state.identifier, this.state.nodeProps);
92 | if (typeof this.props.didNativeUpdate == "function")
93 | await this.props.didNativeUpdate();
94 | this.setState(({ updateState }) => {
95 | return { updateState: updateState == "donext" ? "do" : "done" };
96 | });
97 | } catch (e) {
98 | this.setState({ updateState: "do" });
99 | }
100 | }
101 | }
102 | componentWillUnmount() {
103 | try {
104 | removeNode(this.state.identifier);
105 | if (this.props.removeNode) this.props.removeNode(this.state.identifier);
106 | } catch (e) {}
107 | }
108 | }
109 | corePropTypes = {
110 | eulerAngles,
111 | orientation,
112 | position,
113 | rotation,
114 | scale,
115 | renderingOrder,
116 | opacity,
117 | id: PropTypes.string,
118 | parentNode: PropTypes.string
119 | };
120 | const nodeProps = Object.keys(corePropTypes);
121 | ARBaseNode.propTypes = {
122 | ...corePropTypes,
123 | onPress: PropTypes.func,
124 | onPressIn: PropTypes.func,
125 | onPressOut: PropTypes.func,
126 | willNativeUpdate: PropTypes.func,
127 | didNativeUpdate: PropTypes.func
128 | };
129 | //#endregion
130 | //#region ARNode
131 | const Adoptee = adopt({
132 | session: ,
133 | touch: ,
134 | node: ,
135 | animated:
136 | });
137 | const ARNode = props => {
138 | return (
139 |
140 | {({
141 | session: { isStarted },
142 | touch: { registerNode, removeNode },
143 | node: { nodeID },
144 | animated: { willNativeUpdate, didNativeUpdate }
145 | }) => {
146 | return isStarted ? (
147 |
155 | ) : null;
156 | }}
157 |
158 | );
159 | };
160 | ARNode.propTypes = {
161 | ...ARBaseNode.propTypes
162 | };
163 | //#endregion
164 | //#region Utility functions
165 | const filterObj = obj => {
166 | return pickBy(obj, (v, k) => nodeProps.indexOf(k) > -1);
167 | };
168 |
169 | const propDiff = (a, b, func) => {
170 | if (a === b) return false;
171 | if (a & !b || !a & b) return true;
172 | const af = func ? func(a) : a;
173 | const bf = func ? func(b) : b;
174 | const afk = Object.keys(af);
175 | const bfk = Object.keys(bf);
176 | if (afk.length != bfk.length) return true;
177 | if (
178 | afk.filter(k => {
179 | return bfk.indexOf(k) === -1;
180 | }).length
181 | )
182 | return true;
183 | if (
184 | afk.filter(k => {
185 | if (bf[k] == af[k]) return false;
186 | if (typeof af[k] == "object") {
187 | return propDiff(af[k], bf[k]);
188 | }
189 | return true;
190 | }).length
191 | )
192 | return true;
193 | };
194 | //#endregion
195 | export { ARNode, ARNodeConsumer };
196 | export default ARNode;
197 |
--------------------------------------------------------------------------------
/components/ARPlane.js:
--------------------------------------------------------------------------------
1 | import PropTypes from "prop-types";
2 | import ARGeometry from "./ARGeometry";
3 | import { setPlane } from "../RNSwiftBridge";
4 | export default ARGeometry(
5 | setPlane,
6 | {
7 | width: PropTypes.number,
8 | height: PropTypes.number,
9 | cornerRadius: PropTypes.number,
10 | cornerSegmentCount: PropTypes.number,
11 | widthSegmentCount: PropTypes.number,
12 | heightSegmentCount: PropTypes.number
13 | },
14 | 1,
15 | {
16 | width: 1,
17 | height: 1,
18 | cornerRadius: 0
19 | }
20 | );
21 |
--------------------------------------------------------------------------------
/components/ARProjectedPointProvider.js:
--------------------------------------------------------------------------------
1 | import React, { Component, createContext } from "react";
2 | import { ARPositionConsumer } from "../ARPositionProvider";
3 | import { ARNodeConsumer } from "./ARNode";
4 | import { ARSessionConsumer } from "../ARSessionProvider";
5 | import { adopt } from "react-adopt";
6 | import { projectNode } from "../RNSwiftBridge";
7 |
8 | const { Provider, Consumer } = createContext({ position: {}, orientation: {} });
9 | //#region ARBaseProjectedPointProvider
10 | class ARBaseProjectedPointProvider extends Component {
11 | state = { providerValue: { position: {}, orientation: {} } };
12 | render() {
13 | return (
14 |
15 | {typeof this.props.children == "function"
16 | ? this.props.children(this.state.providerValue)
17 | : this.props.children}
18 |
19 | );
20 | }
21 | static getDerivedStateFromProps(nextProps, prevState) {
22 | const ret = prevState;
23 | ret.todos = {};
24 | if (nextProps.newPosition) {
25 | if (
26 | !prevState.position ||
27 | JSON.stringify(prevState.position) !=
28 | JSON.stringify(nextProps.newPosition)
29 | ) {
30 | ret.todos.updatePosition = true;
31 | ret.position = nextProps.newPosition;
32 | }
33 | }
34 | return ret;
35 | }
36 | componentDidMount() {
37 | this.manageTodos();
38 | }
39 | componentDidUpdate() {
40 | this.manageTodos();
41 | }
42 | manageTodos() {
43 | if (!this.state.todos) return;
44 | Object.keys(this.state.todos).forEach(k => {
45 | const v = this.state.todos[k];
46 | if (typeof this[k] == "function") {
47 | this[k](v);
48 | }
49 | this.setState({ todos: null });
50 | });
51 | }
52 | async updatePosition() {
53 | try {
54 | const pos = await projectNode(this.props.nodeID);
55 | this.setState(({ providerValue }) => {
56 | if (pos.z > 1) {
57 | console.log("hiding because pos is behind me");
58 | if (providerValue.position.x) {
59 | return { providerValue: { position: {}, orientation: {} } };
60 | } else return { providerValue };
61 | }
62 | const z = pos.z;
63 | const x = parseInt(pos.x);
64 | if (x == providerValue.position.x) return { providerValue };
65 | const y = parseInt(pos.y);
66 | if (y == providerValue.position.y) return { providerValue };
67 | return { providerValue: { ...providerValue, position: { x, y, z } } };
68 | });
69 | } catch (e) {
70 | console.log("Error in updatePosition", e);
71 | }
72 | }
73 | }
74 | //#endregion
75 | //#region ARProjectedPointProvider
76 | const Adoptee = adopt({
77 | session: ,
78 | position: ,
79 | node:
80 | });
81 | const ARProjectedPointProvider = props => (
82 |
83 | {({
84 | session: { isStarted },
85 | position: { position, orientation },
86 | node: { nodeID }
87 | }) => {
88 | if (!isStarted) return null;
89 | if (!nodeID) return null;
90 | return (
91 |
97 | );
98 | }}
99 |
100 | );
101 | //#endregion
102 | export default ARProjectedPointProvider;
103 | export { ARProjectedPointProvider, Consumer as ARProjectedPointConsumer };
104 |
--------------------------------------------------------------------------------
/components/ARPyramid.js:
--------------------------------------------------------------------------------
1 | import PropTypes from "prop-types";
2 | import ARGeometry from "./ARGeometry";
3 |
4 | import { setPyramid } from "../RNSwiftBridge";
5 | export default ARGeometry(
6 | setPyramid,
7 | {
8 | width: PropTypes.number,
9 | length: PropTypes.number,
10 | height: PropTypes.number
11 | },
12 | 5,
13 | {
14 | width: 1,
15 | length: 1,
16 | height: 1
17 | }
18 | );
19 |
--------------------------------------------------------------------------------
/components/ARSKLabel.js:
--------------------------------------------------------------------------------
1 | import React, { Component, Children } from "react";
2 | import { processColor } from "react-native";
3 | import {
4 | removeSKNode,
5 | setSKLabelNode,
6 | updateSKLabelNode
7 | } from "../RNSwiftBridge";
8 | import PropTypes from "prop-types";
9 | import pickBy from "lodash/pickBy";
10 | import UUID from "uuid/v4";
11 | import { ARSKNodeProvider, ARSKNodeConsumer } from "./ARSKScene";
12 | class ARBaseSKLabel extends Component {
13 | state = {
14 | identifier: UUID(),
15 | updateState: "doMount"
16 | };
17 | constructor(props) {
18 | super(props);
19 | this.state.providerValue = { SKNodeID: this.state.identifier };
20 | }
21 | async nativeUpdate() {
22 | if (this.state.updateState == "doMount") {
23 | this.setState({ updateState: "Mounting" });
24 | try {
25 | const label = {
26 | ...propFilter(this.props),
27 | name: this.state.identifier
28 | };
29 | const result = await setSKLabelNode(label, this.props.parentSKNode);
30 | this.setState(({ updateState }) => {
31 | return { updateState: updateState == "donext" ? "do" : "done" };
32 | });
33 | } catch (e) {
34 | this.setState({ updateState: "doMount" });
35 | }
36 | } else if (this.state.updateState == "do") {
37 | this.setState({ updateState: "doing" });
38 | try {
39 | const label = {
40 | ...propFilter(this.props),
41 | name: this.state.identifier
42 | };
43 | const result = await updateSKLabelNode(label);
44 | this.setState(({ updateState }) => {
45 | return { updateState: updateState == "donext" ? "do" : "done" };
46 | });
47 | } catch (e) {
48 | this.setState({ updateState: "do" });
49 | }
50 | }
51 | }
52 | componentDidMount() {
53 | this.nativeUpdate();
54 | }
55 | componentDidUpdate() {
56 | this.nativeUpdate();
57 | }
58 | render() {
59 | if (["doMount", "Mounting"].indexOf(this.state.updateState) > -1)
60 | return null;
61 | if (!this.props.children) return null;
62 | return (
63 |
64 | {this.props.children}
65 |
66 | );
67 | }
68 | componentWillUnmount() {
69 | const result = removeSKNode(this.state.identifier);
70 | }
71 | static getDerivedStateFromProps(nextProps, prevState) {
72 | var ret = prevState;
73 | if (propDiff(nextProps, prevState.SKProps)) {
74 | ret.SKProps = propFilter(nextProps);
75 | if (["doMount", "Mounting"].indexOf(prevState.updateState) == -1) {
76 | ret.updateState = prevState.updateState == "doing" ? "donext" : "do";
77 | }
78 | }
79 | return ret;
80 | }
81 | }
82 | ARBaseSKLabel.propTypes = {
83 | position: PropTypes.shape({
84 | x: PropTypes.number,
85 | y: PropTypes.number
86 | }),
87 | parentSKNode: PropTypes.string,
88 | text: PropTypes.string,
89 | id: PropTypes.string,
90 | fontName: PropTypes.string,
91 | fontSize: PropTypes.number,
92 | fontColor: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), // Note this requires a preprocessed color
93 | width: PropTypes.number,
94 | horizontalAlignment: PropTypes.string,
95 | verticalAlignment: PropTypes.string,
96 | allowScaling: PropTypes.bool,
97 | lineBreak: PropTypes.string,
98 | lines: PropTypes.number
99 | };
100 |
101 | const SKLabelKeys = Object.keys(ARBaseSKLabel.propTypes);
102 | const ARSKLabel = props => {
103 | return (
104 |
105 | {({ SKNodeID, height, width }) => {
106 | return (
107 |
113 | );
114 | }}
115 |
116 | );
117 | };
118 | ARSKLabel.defaultProps = {
119 | allowScaling: true
120 | };
121 |
122 | const propFilter = props => {
123 | const temp = {
124 | ...pickBy(props, (v, k) => SKLabelKeys.indexOf(k) > -1)
125 | };
126 | if (typeof temp.fontColor == "string")
127 | temp.fontColor = processColor(temp.fontColor);
128 | return temp;
129 | };
130 |
131 | const propDiff = (a, b) => {
132 | if (a === b) return false;
133 | if (a & !b || !a & b) {
134 | return true;
135 | }
136 | const af = propFilter(a);
137 | const bf = propFilter(b);
138 |
139 | const afk = Object.keys(af);
140 | const bfk = Object.keys(bf);
141 | if (afk.length != bfk.length) {
142 | return true;
143 | }
144 | if (
145 | afk.filter(k => {
146 | return bfk.indexOf(k) === -1;
147 | }).length
148 | ) {
149 | return true;
150 | }
151 | if (
152 | afk.filter(k => {
153 | const t1 = bf[k] == af[k];
154 | if (t1) return false;
155 | if (typeof bf[k] === "object") {
156 | return JSON.stringify(bf[k]) != JSON.stringify(af[k]);
157 | } else {
158 | return true;
159 | }
160 | }).length
161 | ) {
162 | return true;
163 | }
164 | };
165 |
166 | ARSKLabel.propTypes = { ...ARBaseSKLabel.propTypes };
167 | export { ARSKLabel, ARSKNodeConsumer };
168 | export default ARSKLabel;
169 |
--------------------------------------------------------------------------------
/components/ARSKScene.js:
--------------------------------------------------------------------------------
1 | import React, { Component, createContext } from "react";
2 | import { addSKScene, removeSKScene, updateSKScene } from "../RNSwiftBridge";
3 | import { processColor } from "react-native";
4 | import PropTypes from "prop-types";
5 | import pickBy from "lodash/pickBy";
6 | import UUID from "uuid/v4";
7 | import { ARMaterialPropertyConsumer } from "./ARMaterialProperty";
8 | const {
9 | Provider: ARSKNodeProvider,
10 | Consumer: ARSKNodeConsumer
11 | } = createContext({});
12 | class ARBaseSKScene extends Component {
13 | state = {
14 | identifier: UUID(),
15 | updateState: "doMount" // "doMount", "Mounting", "donext", "do", "doing", "done"
16 | };
17 | updateProviderValue() {
18 | this.setState({
19 | providerValue: {
20 | SKNodeID: this.state.identifier,
21 | height: this.props.height,
22 | width: this.props.width
23 | },
24 | todos: {}
25 | });
26 | }
27 | constructor(props) {
28 | super(props);
29 | this.state.providerValue = {
30 | SKNodeID: this.state.identifier,
31 | height: this.props.height,
32 | width: this.props.width
33 | };
34 | }
35 | async nativeUpdate() {
36 | if (this.state.updateState == "doMount") {
37 | this.setState({ updateState: "Mounting" });
38 | try {
39 | const filteredProps = propFilter(this.props);
40 | const scene = {
41 | ...propFilter(this.props),
42 | name: this.state.identifier
43 | };
44 | const result = await addSKScene(
45 | scene,
46 | this.props.parentNode,
47 | this.props.index,
48 | this.props.materialProperty
49 | );
50 | this.setState(({ updateState }) => {
51 | return { updateState: updateState == "donext" ? "do" : "done" };
52 | });
53 | } catch (e) {
54 | this.setState({ updateState: "doMount" });
55 | }
56 | } else if (this.state.updateState == "do") {
57 | this.setState({ updateState: "doing" });
58 | try {
59 | const scene = {
60 | ...propFilter(this.props),
61 | name: this.state.identifier
62 | };
63 | await updateSKScene(
64 | scene,
65 | this.props.parentNode,
66 | this.props.index,
67 | this.props.materialProperty
68 | );
69 | this.setState(({ updateState }) => {
70 | return { updateState: updateState == "donext" ? "do" : "done" };
71 | });
72 | } catch (e) {
73 | this.setState({ updateState: "do" });
74 | }
75 | const scene = {};
76 | }
77 | }
78 | static getDerivedStateFromProps(nextProps, prevState) {
79 | var ret = prevState;
80 | ret.todos = {};
81 | if (nextProps.id && prevState.identifier != nextProps.id) {
82 | ret.identifier = nextProps.id;
83 | if (["doMount", "Mounting"].indexOf(ret.updateState) == -1)
84 | ret.updateState =
85 | ["doing", "Mounting"].indexOf(ret.updateState) == -1
86 | ? "do"
87 | : "donext";
88 | }
89 | if (propDiff(prevState.sceneProps, nextProps, propFilter)) {
90 | ret.sceneProps = propFilter(nextProps);
91 | if (["doMount", "Mounting"].indexOf(ret.updateState) == -1)
92 | ret.updateState =
93 | ["doing", "Mounting"].indexOf(ret.updateState) == -1
94 | ? "do"
95 | : "donext";
96 | }
97 | if (
98 | nextProps.height != prevState.providerValue.height ||
99 | nextProps.width != prevState.providerValue.width
100 | ) {
101 | ret.todos["updateProviderValue"] = true;
102 | }
103 | return ret;
104 | }
105 | componentDidMount() {
106 | this.manageTodos();
107 | this.nativeUpdate();
108 | }
109 | componentDidUpdate() {
110 | this.manageTodos();
111 | this.nativeUpdate();
112 | }
113 | manageTodos() {
114 | if (this.state.todos && Object.keys(this.state.todos).length) {
115 | Object.keys(this.state.todos).forEach(k => {
116 | if (typeof this[k] == "function") this[k](this.state.todos[k]);
117 | });
118 | this.setState({ todos: {} });
119 | }
120 | }
121 | render() {
122 | if (!this.props.children) return null;
123 | if (["doMount", "Mounting"].indexOf(this.state.updateState) > -1)
124 | return null;
125 | return (
126 |
127 | {typeof this.props.children == "function" ? (
128 |
129 | {value => {
130 | return this.props.children(value);
131 | }}
132 |
133 | ) : (
134 | this.props.children
135 | )}
136 |
137 | );
138 | }
139 | componentWillUnmount() {
140 | removeSKScene(
141 | this.props.parentNode,
142 | this.props.index,
143 | this.props.materialProperty
144 | );
145 | }
146 | }
147 |
148 | ARBaseSKScene.propTypes = {
149 | height: PropTypes.number,
150 | width: PropTypes.number,
151 | id: PropTypes.string,
152 | color: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
153 | parentNode: PropTypes.string,
154 | index: PropTypes.number,
155 | materialProperty: PropTypes.string
156 | };
157 |
158 | ARBaseSKScene.defaultProps = {
159 | height: 100,
160 | width: 100
161 | };
162 | const sceneKeys = Object.keys(ARBaseSKScene.propTypes);
163 |
164 | const ARSKScene = props => {
165 | return (
166 |
167 | {({ parentNode, materialProperty, index }) => {
168 | return (
169 |
172 | );
173 | }}
174 |
175 | );
176 | };
177 | export { ARSKScene, ARSKNodeConsumer, ARSKNodeProvider };
178 | export default ARSKScene;
179 |
180 | const propFilter = props => {
181 | const temp = {
182 | ...pickBy(props, (v, k) => sceneKeys.indexOf(k) > -1)
183 | };
184 | if (typeof temp.color == "string") temp.color = processColor(temp.color);
185 | return temp;
186 | };
187 |
188 | const propDiff = (a, b) => {
189 | if (a === b) return false;
190 | if (a & !b || !a & b) return true;
191 | const af = propFilter(a);
192 | const bf = propFilter(b);
193 |
194 | const afk = Object.keys(af);
195 | const bfk = Object.keys(bf);
196 | if (afk.length != bfk.length) return true;
197 | if (
198 | afk.filter(k => {
199 | return bfk.indexOf(k) === -1;
200 | }).length
201 | )
202 | return true;
203 | if (
204 | afk.filter(k => {
205 | return bf[k] != af[k];
206 | }).length
207 | )
208 | return true;
209 | };
210 |
--------------------------------------------------------------------------------
/components/ARSKVideo.js:
--------------------------------------------------------------------------------
1 | import React, { Component, Children } from "react";
2 | import { processColor } from "react-native";
3 | import {
4 | removeSKNode,
5 | setSKVideoNode,
6 | updateSKVideoNode
7 | } from "../RNSwiftBridge";
8 | import PropTypes from "prop-types";
9 | import pickBy from "lodash/pickBy";
10 | import UUID from "uuid/v4";
11 | import { ARSKNodeProvider, ARSKNodeConsumer } from "./ARSKScene";
12 | class ARBaseSKVideo extends Component {
13 | state = {
14 | identifier: UUID(),
15 | updateState: "doMount"
16 | };
17 | constructor(props) {
18 | super(props);
19 | this.state.providerValue = { SKNodeID: this.state.identifier };
20 | }
21 | async nativeUpdate() {
22 | if (this.state.updateState == "doMount") {
23 | this.setState({ updateState: "Mounting" });
24 | try {
25 | const label = {
26 | ...propFilter(this.props),
27 | name: this.state.identifier
28 | };
29 | const result = await setSKVideoNode(label, this.props.parentSKNode);
30 | this.setState(({ updateState }) => {
31 | return { updateState: updateState == "donext" ? "do" : "done" };
32 | });
33 | } catch (e) {
34 | this.setState({ updateState: "doMount" });
35 | }
36 | } else if (this.state.updateState == "do") {
37 | this.setState({ updateState: "doing" });
38 | try {
39 | const label = {
40 | ...propFilter(this.props),
41 | name: this.state.identifier
42 | };
43 | const result = await updateSKVideoNode(label);
44 | this.setState(({ updateState }) => {
45 | return { updateState: updateState == "donext" ? "do" : "done" };
46 | });
47 | } catch (e) {
48 | this.setState({ updateState: "do" });
49 | }
50 | }
51 | }
52 | componentDidMount() {
53 | this.nativeUpdate();
54 | }
55 | componentDidUpdate() {
56 | this.nativeUpdate();
57 | }
58 | render() {
59 | if (["doMount", "Mounting"].indexOf(this.state.updateState) > -1)
60 | return null;
61 | if (!this.props.children) return null;
62 | return (
63 |
64 | {this.props.children}
65 |
66 | );
67 | }
68 | componentWillUnmount() {
69 | const result = removeSKNode(this.state.identifier);
70 | }
71 | static getDerivedStateFromProps(nextProps, prevState) {
72 | var ret = prevState;
73 | if (propDiff(nextProps, prevState.SKProps)) {
74 | ret.SKProps = propFilter(nextProps);
75 | if (["doMount", "Mounting"].indexOf(prevState.updateState) == -1) {
76 | ret.updateState = prevState.updateState == "doing" ? "donext" : "do";
77 | }
78 | }
79 | return ret;
80 | }
81 | }
82 | ARBaseSKVideo.propTypes = {
83 | //General to Nodes
84 | position: PropTypes.shape({
85 | x: PropTypes.number,
86 | y: PropTypes.number
87 | }),
88 | parentSKNode: PropTypes.string,
89 | text: PropTypes.string,
90 | id: PropTypes.string,
91 | //Specific to video node
92 | width: PropTypes.number,
93 | height: PropTypes.number,
94 | url: PropTypes.string,
95 | path: PropTypes.string,
96 | isPlaying: PropTypes.bool
97 | };
98 |
99 | const SKVideoKeys = Object.keys(ARBaseSKVideo.propTypes);
100 | const ARSKVideo = props => {
101 | return (
102 |
103 | {({ SKNodeID, height, width }) => {
104 | return (
105 |
111 | );
112 | }}
113 |
114 | );
115 | };
116 | ARSKVideo.defaultProps = {
117 | isPlaying: true
118 | };
119 |
120 | const propFilter = props => {
121 | const temp = {
122 | ...pickBy(props, (v, k) => SKVideoKeys.indexOf(k) > -1)
123 | };
124 | return temp;
125 | };
126 |
127 | const propDiff = (a, b) => {
128 | if (a === b) return false;
129 | if (a & !b || !a & b) {
130 | return true;
131 | }
132 | const af = propFilter(a);
133 | const bf = propFilter(b);
134 |
135 | const afk = Object.keys(af);
136 | const bfk = Object.keys(bf);
137 | if (afk.length != bfk.length) {
138 | return true;
139 | }
140 | if (
141 | afk.filter(k => {
142 | return bfk.indexOf(k) === -1;
143 | }).length
144 | ) {
145 | return true;
146 | }
147 | if (
148 | afk.filter(k => {
149 | const t1 = bf[k] == af[k];
150 | if (t1) return false;
151 | if (typeof bf[k] === "object") {
152 | return JSON.stringify(bf[k]) != JSON.stringify(af[k]);
153 | } else {
154 | return true;
155 | }
156 | }).length
157 | ) {
158 | return true;
159 | }
160 | };
161 |
162 | ARSKVideo.propTypes = { ...ARBaseSKVideo.propTypes };
163 | export { ARSKVideo, ARSKNodeConsumer };
164 | export default ARSKVideo;
165 |
--------------------------------------------------------------------------------
/components/ARScene.js:
--------------------------------------------------------------------------------
1 | import PropTypes from "prop-types";
2 | import ARGeometry from "./ARGeometry";
3 | import { setScene } from "../RNSwiftBridge";
4 | export default ARGeometry(
5 | async ({ path }, nodeID) => {
6 | return await setScene(nodeID, path);
7 | },
8 | {
9 | path: PropTypes.string
10 | },
11 | 0
12 | );
13 |
--------------------------------------------------------------------------------
/components/ARShape.js:
--------------------------------------------------------------------------------
1 | import PropTypes from "prop-types";
2 | import ARGeometry from "./ARGeometry";
3 |
4 | import { setShape } from "../RNSwiftBridge";
5 | export default ARGeometry(
6 | setShape,
7 | {
8 | extrusion: PropTypes.number,
9 | pathSvg: PropTypes.string.isRequired,
10 | pathFlatness: PropTypes.number,
11 | chamferMode: PropTypes.number,
12 | chamferRadius: PropTypes.number,
13 | chamferProfilePathSvg: PropTypes.string,
14 | chamferProfilePathFlatness: PropTypes.number
15 | },
16 | props => {
17 | var temp = 4; // Default where there is extrusion and chamfer but only one side - bezeled extruded disc
18 | if (!props.extrusion) {
19 | temp = 1; // Basically a plane
20 | } else if (!props.chamferRadius) {
21 | temp = 3; // There is extrusion but no chamfer - like an extruded disc
22 | } else if (props.chamferMode == 0) {
23 | temp = 5; // THere is extrusion and double-chamfer - extruded disc with bezeling front and back
24 | }
25 | return temp;
26 | },
27 | {
28 | extrusion: 1.0,
29 | chamferMode: 0
30 | }
31 | );
32 |
--------------------------------------------------------------------------------
/components/ARSphere.js:
--------------------------------------------------------------------------------
1 | import PropTypes from "prop-types";
2 | import ARGeometry from "./ARGeometry";
3 |
4 | import { setSphere } from "../RNSwiftBridge";
5 | export default ARGeometry(
6 | setSphere,
7 | {
8 | radius: PropTypes.number
9 | },
10 | 1,
11 | {
12 | radius: 0.5
13 | }
14 | );
15 |
--------------------------------------------------------------------------------
/components/ARText.js:
--------------------------------------------------------------------------------
1 | import PropTypes from "prop-types";
2 | import ARGeometry from "./ARGeometry";
3 |
4 | import { setText } from "../RNSwiftBridge";
5 | export default ARGeometry(
6 | setText,
7 | {
8 | text: PropTypes.string,
9 | fontName: PropTypes.string,
10 | // weight: PropTypes.string,
11 | size: PropTypes.number,
12 | depth: PropTypes.number,
13 | chamfer: PropTypes.number
14 | },
15 | ({ chamfer }) => {
16 | if (chamfer) return 4;
17 | return 3;
18 | },
19 | {
20 | size: 12,
21 | depth: 0.1,
22 | chamfer: 0
23 | }
24 | );
25 |
--------------------------------------------------------------------------------
/components/ARTorus.js:
--------------------------------------------------------------------------------
1 | import PropTypes from "prop-types";
2 | import ARGeometry from "./ARGeometry";
3 |
4 | import { setTorus } from "../RNSwiftBridge";
5 | export default ARGeometry(
6 | setTorus,
7 | {
8 | ringR: PropTypes.number,
9 | pipeR: PropTypes.number
10 | },
11 | 1,
12 | {
13 | ringR: 0.5,
14 | pipeR: 0.25
15 | }
16 | );
17 |
--------------------------------------------------------------------------------
/components/ARTube.js:
--------------------------------------------------------------------------------
1 | import PropTypes from "prop-types";
2 | import ARGeometry from "./ARGeometry";
3 |
4 | import { setTube } from "../RNSwiftBridge";
5 | export default ARGeometry(
6 | setTube,
7 | {
8 | innerR: PropTypes.number,
9 | outerR: PropTypes.number,
10 | height: PropTypes.number
11 | },
12 | ({ innerR, outerR }) => {
13 | if (innerR == outerR) return 2;
14 | return 4;
15 | },
16 | {
17 | innerR: 0.25,
18 | outerR: 0.5,
19 | height: 1
20 | }
21 | );
22 |
--------------------------------------------------------------------------------
/components/ARZoomResponder.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from "react";
2 | import { Text, View, PanResponder, Image } from "react-native";
3 |
4 | function calcDistance(x1, y1, x2, y2) {
5 | let dx = Math.abs(x1 - x2);
6 | let dy = Math.abs(y1 - y2);
7 | return Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
8 | }
9 |
10 | function calcCenter(x1, y1, x2, y2) {
11 | function middle(p1, p2) {
12 | return p1 > p2 ? p1 - (p1 - p2) / 2 : p2 - (p2 - p1) / 2;
13 | }
14 |
15 | return {
16 | x: middle(x1, x2),
17 | y: middle(y1, y2)
18 | };
19 | }
20 |
21 | function maxOffset(offset, windowDimension, imageDimension) {
22 | let max = windowDimension - imageDimension;
23 | if (max >= 0) {
24 | return 0;
25 | }
26 | return offset < max ? max : offset;
27 | }
28 |
29 | function calcOffsetByZoom(width, height, imageWidth, imageHeight, zoom) {
30 | let xDiff = imageWidth * zoom - width;
31 | let yDiff = imageHeight * zoom - height;
32 | return {
33 | left: -xDiff / 2,
34 | top: -yDiff / 2
35 | };
36 | }
37 |
38 | class ARZoomResponder extends Component {
39 | constructor(props) {
40 | super(props);
41 |
42 | this._onLayout = this._onLayout.bind(this);
43 |
44 | this.state = {
45 | zoom: null,
46 | minZoom: null,
47 | layoutKnown: false,
48 | isZooming: false,
49 | isMoving: false,
50 | initialDistance: null,
51 | initialX: null,
52 | initalY: null,
53 | offsetTop: 0,
54 | offsetLeft: 0,
55 | initialTop: 0,
56 | initialLeft: 0,
57 | initialTopWithoutZoom: 0,
58 | initialLeftWithoutZoom: 0,
59 | initialZoom: 1,
60 | top: 0,
61 | left: 0
62 | };
63 | }
64 |
65 | processPinch(x1, y1, x2, y2) {
66 | let distance = calcDistance(x1, y1, x2, y2);
67 | let center = calcCenter(x1, y1, x2, y2);
68 |
69 | if (!this.state.isZooming) {
70 | let offsetByZoom = calcOffsetByZoom(
71 | this.state.width,
72 | this.state.height,
73 | this.props.imageWidth,
74 | this.props.imageHeight,
75 | this.state.zoom
76 | );
77 | this.setState({
78 | isZooming: true,
79 | initialDistance: distance,
80 | initialX: center.x,
81 | initialY: center.y,
82 | initialTop: this.state.top,
83 | initialLeft: this.state.left,
84 | initialZoom: this.state.zoom,
85 | initialTopWithoutZoom: this.state.top - offsetByZoom.top,
86 | initialLeftWithoutZoom: this.state.left - offsetByZoom.left
87 | });
88 | } else {
89 | let touchZoom = distance / this.state.initialDistance;
90 | let zoom =
91 | touchZoom * this.state.initialZoom > this.state.minZoom
92 | ? touchZoom * this.state.initialZoom
93 | : this.state.minZoom;
94 |
95 | let offsetByZoom = calcOffsetByZoom(
96 | this.state.width,
97 | this.state.height,
98 | this.props.imageWidth,
99 | this.props.imageHeight,
100 | zoom
101 | );
102 | let left =
103 | this.state.initialLeftWithoutZoom * touchZoom + offsetByZoom.left;
104 | let top = this.state.initialTopWithoutZoom * touchZoom + offsetByZoom.top;
105 |
106 | this.setState({
107 | zoom: zoom,
108 | left: 0,
109 | top: 0,
110 | left:
111 | left > 0
112 | ? 0
113 | : maxOffset(left, this.state.width, this.props.imageWidth * zoom),
114 | top:
115 | top > 0
116 | ? 0
117 | : maxOffset(top, this.state.height, this.props.imageHeight * zoom)
118 | });
119 | }
120 | }
121 |
122 | processTouch(x, y) {
123 | if (!this.state.isMoving) {
124 | this.setState({
125 | isMoving: true,
126 | initialX: x,
127 | initialY: y,
128 | initialTop: this.state.top,
129 | initialLeft: this.state.left
130 | });
131 | } else {
132 | let left = this.state.initialLeft + x - this.state.initialX;
133 | let top = this.state.initialTop + y - this.state.initialY;
134 |
135 | this.setState({
136 | left:
137 | left > 0
138 | ? 0
139 | : maxOffset(
140 | left,
141 | this.state.width,
142 | this.props.imageWidth * this.state.zoom
143 | ),
144 | top:
145 | top > 0
146 | ? 0
147 | : maxOffset(
148 | top,
149 | this.state.height,
150 | this.props.imageHeight * this.state.zoom
151 | )
152 | });
153 | }
154 | }
155 |
156 | _onLayout(event) {
157 | let layout = event.nativeEvent.layout;
158 |
159 | if (
160 | layout.width === this.state.width &&
161 | layout.height === this.state.height
162 | ) {
163 | return;
164 | }
165 |
166 | let zoom = layout.width / this.props.imageWidth;
167 |
168 | let offsetTop =
169 | layout.height > this.props.imageHeight * zoom
170 | ? (layout.height - this.props.imageHeight * zoom) / 2
171 | : 0;
172 |
173 | this.setState({
174 | layoutKnown: true,
175 | width: layout.width,
176 | height: layout.height,
177 | zoom: zoom,
178 | offsetTop: offsetTop,
179 | minZoom: zoom
180 | });
181 | }
182 |
183 | componentWillMount() {
184 | this._panResponder = PanResponder.create({
185 | onStartShouldSetPanResponder: (evt, gestureState) => true,
186 | onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
187 | onMoveShouldSetPanResponder: (evt, gestureState) => true,
188 | onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
189 | onPanResponderGrant: (evt, gestureState) => {},
190 | onPanResponderMove: (evt, gestureState) => {
191 | let touches = evt.nativeEvent.touches;
192 | if (touches.length == 2) {
193 | let touch1 = touches[0];
194 | let touch2 = touches[1];
195 |
196 | this.processPinch(
197 | touches[0].pageX,
198 | touches[0].pageY,
199 | touches[1].pageX,
200 | touches[1].pageY
201 | );
202 | } else if (touches.length == 1 && !this.state.isZooming) {
203 | this.processTouch(touches[0].pageX, touches[0].pageY);
204 | }
205 | },
206 |
207 | onPanResponderTerminationRequest: (evt, gestureState) => true,
208 | onPanResponderRelease: (evt, gestureState) => {
209 | this.setState({
210 | isZooming: false,
211 | isMoving: false
212 | });
213 | },
214 | onPanResponderTerminate: (evt, gestureState) => {},
215 | onShouldBlockNativeResponder: (evt, gestureState) => true
216 | });
217 | }
218 |
219 | render() {
220 | return (
221 |
226 |
236 |
237 | );
238 | }
239 | }
240 |
241 | ZoomableImage.propTypes = {
242 | imageWidth: PropTypes.number.isRequired,
243 | imageHeight: PropTypes.number.isRequired,
244 | source: PropTypes.object.isRequired
245 | };
246 | export default ZoomableImage;
247 |
--------------------------------------------------------------------------------
/components/old/ARSprite.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import withAnimationFrame from "@panter/react-animation-frame";
3 |
4 | import { NativeModules, Animated } from "react-native";
5 |
6 | import { position } from "./lib/propTypes";
7 |
8 | const ARKitManager = NativeModules.ARARViewManager;
9 |
10 | const ARSprite = withAnimationFrame(
11 | class extends Component {
12 | constructor(props) {
13 | super(props);
14 | this.state = {
15 | zIndex: new Animated.Value(),
16 | pos2D: new Animated.ValueXY() // inits to zero
17 | };
18 | }
19 | onAnimationFrame() {
20 | ARKitManager.projectPoint(this.props.position).then(
21 | Animated.event([
22 | {
23 | x: this.state.pos2D.x,
24 | y: this.state.pos2D.y,
25 | z: this.state.zIndex
26 | }
27 | ])
28 | );
29 | }
30 |
31 | render() {
32 | return (
33 |
40 | {this.props.children}
41 |
42 | );
43 | }
44 | }
45 | );
46 |
47 | ARSprite.propTypes = {
48 | position
49 | };
50 |
51 | export default ARSprite;
52 |
--------------------------------------------------------------------------------
/components/propTypes.js:
--------------------------------------------------------------------------------
1 | import { NativeModules } from "react-native";
2 | import { values } from "lodash";
3 | import PropTypes from "prop-types";
4 |
5 | const { ARSceneManager } = NativeModules;
6 |
7 | export const position = PropTypes.shape({
8 | x: PropTypes.number,
9 | y: PropTypes.number,
10 | z: PropTypes.number
11 | });
12 |
13 | export const scale = PropTypes.number;
14 | export const categoryBitMask = PropTypes.number;
15 | export const transition = PropTypes.shape({
16 | duration: PropTypes.number
17 | });
18 | export const eulerAngles = PropTypes.shape({
19 | x: PropTypes.number,
20 | y: PropTypes.number,
21 | z: PropTypes.number
22 | });
23 |
24 | export const rotation = PropTypes.shape({
25 | x: PropTypes.number,
26 | y: PropTypes.number,
27 | z: PropTypes.number,
28 | w: PropTypes.number
29 | });
30 |
31 | export const orientation = PropTypes.shape({
32 | x: PropTypes.number,
33 | y: PropTypes.number,
34 | z: PropTypes.number,
35 | w: PropTypes.number
36 | });
37 | export const shaders = PropTypes.shape({
38 | [ARSceneManager.ShaderModifierEntryPoint.Geometry]: PropTypes.string,
39 | [ARSceneManager.ShaderModifierEntryPoint.Surface]: PropTypes.string,
40 | [ARSceneManager.ShaderModifierEntryPoint.LightingModel]: PropTypes.string,
41 | [ARSceneManager.ShaderModifierEntryPoint.Fragment]: PropTypes.string
42 | });
43 |
44 | export const lightingModel = PropTypes.oneOf(
45 | values(ARSceneManager.LightingModel)
46 | );
47 |
48 | export const castsShadow = PropTypes.bool;
49 | export const renderingOrder = PropTypes.number;
50 | export const blendMode = PropTypes.oneOf(values(ARSceneManager.BlendMode));
51 | export const chamferMode = PropTypes.oneOf(values(ARSceneManager.ChamferMode));
52 | export const color = PropTypes.string;
53 | export const fillMode = PropTypes.oneOf(values(ARSceneManager.FillMode));
54 |
55 | export const lightType = PropTypes.oneOf(values(ARSceneManager.LightType));
56 | export const shadowMode = PropTypes.oneOf(values(ARSceneManager.ShadowMode));
57 | export const colorBufferWriteMask = PropTypes.oneOf(
58 | values(ARSceneManager.ColorMask)
59 | );
60 |
61 | export const opacity = PropTypes.number;
62 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import ARBox from "./components/ARBox";
2 | import ARCapsule from "./components/ARCapsule";
3 | import ARCone from "./components/ARCone";
4 | import ARCylinder from "./components/ARCylinder";
5 | import ARMonoView from "./ARMonoView";
6 | import ARPlane from "./components/ARPlane";
7 | import ARPyramid from "./components/ARPyramid";
8 | import ARSphere from "./components/ARSphere";
9 | import ARText from "./components/ARText";
10 | import ARTorus from "./components/ARTorus";
11 | import ARTube from "./components/ARTube";
12 | import ARNode from "./components/ARNode";
13 | import ARMaterial from "./components/ARMaterial";
14 | import ARMaterialProperty from "./components/ARMaterialProperty";
15 | import ARMaterials from "./components/ARMaterials";
16 | import ARTouchableMonoView from "./ARTouchableMonoView";
17 | import { ARSKScene, ARSKNodeConsumer } from "./components/ARSKScene";
18 | import ARSKLabel from "./components/ARSKLabel";
19 | import ARAnimatedProvider from "./ARAnimatedProvider";
20 | import ARScene from "./components/ARScene";
21 | import ARModel from "./components/ARModel";
22 | import { ARSessionConsumer, ARSessionProvider } from "./ARSessionProvider";
23 | import { ARPositionProvider, ARPositionConsumer } from "./ARPositionProvider";
24 | import { ARTrackingConsumer, ARTrackingProvider } from "./ARTrackingProvider";
25 | import ARShape from "./components/ARShape";
26 | import ARLight from "./components/ARLight";
27 | import ARSKVideo from "./components/ARSKVideo";
28 | import {
29 | ARProjectedPointProvider,
30 | ARProjectedPointConsumer
31 | } from "./components/ARProjectedPointProvider";
32 | import ARProjectedView from "./ARProjectedView";
33 | export {
34 | ARMonoView,
35 | ARBox,
36 | ARSphere,
37 | ARCylinder,
38 | ARCone,
39 | ARPyramid,
40 | ARTube,
41 | ARTorus,
42 | ARCapsule,
43 | ARPlane,
44 | ARText,
45 | ARNode,
46 | ARMaterial,
47 | ARMaterialProperty,
48 | ARMaterials,
49 | ARTouchableMonoView,
50 | ARSKScene,
51 | ARSKLabel,
52 | ARSessionConsumer,
53 | ARSessionProvider,
54 | ARAnimatedProvider,
55 | ARPositionProvider,
56 | ARPositionConsumer,
57 | ARTrackingConsumer,
58 | ARTrackingProvider,
59 | ARScene,
60 | ARModel,
61 | ARShape,
62 | ARLight,
63 | ARSKVideo,
64 | ARSKNodeConsumer,
65 | ARProjectedPointConsumer,
66 | ARProjectedPointProvider,
67 | ARProjectedView
68 | };
69 | import React, { Component } from "react";
70 | import PropTypes from "prop-types";
71 | //#region Materials
72 | export const ARColor = ({ color, index }) => {
73 | if (typeof index == "undefined") {
74 | return (
75 |
76 |
77 |
78 | );
79 | } else {
80 | return (
81 |
82 |
83 |
84 | );
85 | }
86 | };
87 | export const ARTexture = ({ path, index }) => {
88 | if (typeof index == "undefined") {
89 | return (
90 |
91 |
92 |
93 | );
94 | } else {
95 | return (
96 |
97 |
98 |
99 | );
100 | }
101 | };
102 | //#endregion
103 | const ARColoredGeometry = G => props => {
104 | return (
105 |
106 |
107 |
108 | );
109 | };
110 | const ARTexturedGeometry = G => props => {
111 | return (
112 |
113 |
114 |
115 | );
116 | };
117 | //#region Geometries
118 | export const ARColoredBox = ARColoredGeometry(ARBox);
119 | export const ARColoredCylinder = ARColoredGeometry(ARCylinder);
120 | export const ARColoredCone = ARColoredGeometry(ARCone);
121 | export const ARColoredCapsule = ARColoredGeometry(ARCapsule);
122 | export const ARColoredPlane = ARColoredGeometry(ARPlane);
123 | export const ARColoredPyramid = ARColoredGeometry(ARPyramid);
124 | export const ARColoredShape = ARColoredGeometry(ARShape);
125 | export const ARColoredSphere = ARColoredGeometry(ARSphere);
126 | export const ARColoredText = ARColoredGeometry(ARText);
127 | export const ARColoredTorus = ARColoredGeometry(ARTorus);
128 | export const ARColoredTube = ARColoredGeometry(ARTube);
129 |
130 | export const ARTexturedBox = ARTexturedGeometry(ARBox);
131 | export const ARTexturedCylinder = ARTexturedGeometry(ARCylinder);
132 | export const ARTexturedCone = ARTexturedGeometry(ARCone);
133 | export const ARTexturedCapsule = ARTexturedGeometry(ARCapsule);
134 | export const ARTexturedPlane = ARTexturedGeometry(ARTexturedPlane);
135 | export const ARTexturedPyramid = ARTexturedGeometry(ARTexturedPyramid);
136 | export const ARTexturedShape = ARTexturedGeometry(ARShape);
137 | export const ARTexturedSphere = ARTexturedGeometry(ARSphere);
138 | export const ARTexturedText = ARTexturedGeometry(ARText);
139 | export const ARTexturedTorus = ARTexturedGeometry(ARTorus);
140 | export const ARTexturedTube = ARTexturedGeometry(ARTube);
141 | //#endregion
142 | //#region adding geometries to nodes
143 | const GeoNode = G => props => {
144 | return (
145 |
146 |
147 |
148 | );
149 | };
150 |
151 | export const ARBoxNode = GeoNode(ARBox);
152 | export const ARCapsuleNode = GeoNode(ARCapsule);
153 | export const ARConeNode = GeoNode(ARCone);
154 | export const ARCylinderNode = GeoNode(ARCylinder);
155 | export const ARPlaneNode = GeoNode(ARPlane);
156 | export const ARPyramidNode = GeoNode(ARPyramid);
157 | export const ARShapeNode = GeoNode(ARShape);
158 | export const ARSphereNode = GeoNode(ARSphere);
159 | export const ARTorusNode = GeoNode(ARTorus);
160 | export const ARTubeNode = GeoNode(ARTube);
161 | export const ARTextNode = GeoNode(ARText);
162 | export const ARColoredBoxNode = GeoNode(ARColoredBox);
163 | export const ARColoredCapsuleNode = GeoNode(ARColoredCapsule);
164 | export const ARColoredConeNode = GeoNode(ARColoredCone);
165 | export const ARColoredCylinderNode = GeoNode(ARColoredCylinder);
166 | export const ARColoredPlaneNode = GeoNode(ARColoredPlane);
167 | export const ARColoredPyramidNode = GeoNode(ARColoredPyramid);
168 | export const ARColoredShapeNode = GeoNode(ARColoredShape);
169 | export const ARColoredSphereNode = GeoNode(ARColoredSphere);
170 | export const ARColoredTorusNode = GeoNode(ARColoredTorus);
171 | export const ARColoredTubeNode = GeoNode(ARColoredTube);
172 | export const ARColoredTextNode = GeoNode(ARColoredText);
173 | export const ARTexturedBoxNode = GeoNode(ARTexturedBox);
174 | export const ARTexturedCapsuleNode = GeoNode(ARTexturedCapsule);
175 | export const ARTexturedConeNode = GeoNode(ARTexturedCone);
176 | export const ARTexturedCylinderNode = GeoNode(ARTexturedCylinder);
177 | export const ARTexturedPlaneNode = GeoNode(ARTexturedPlane);
178 | export const ARTexturedPyramidNode = GeoNode(ARTexturedPyramid);
179 | export const ARTexturedShapeNode = GeoNode(ARTexturedShape);
180 | export const ARTexturedSphereNode = GeoNode(ARTexturedSphere);
181 | export const ARTexturedTorusNode = GeoNode(ARTexturedTorus);
182 | export const ARTexturedTubeNode = GeoNode(ARTexturedTube);
183 | export const ARTexturedTextNode = GeoNode(ARTexturedText);
184 | //#endregion
185 |
186 | export const ARPlaneScene = props => {
187 | return (
188 |
189 |
190 |
191 |
196 |
197 |
198 |
199 | );
200 | };
201 | //#sign
202 |
203 | export const ARCenteredSKLabel = props => {
204 | return (
205 |
206 | {({ height, width }) => {
207 | return (
208 |
216 | );
217 | }}
218 |
219 | );
220 | };
221 | export const ARSign = props => {
222 | const { height, width, ...labelProps } = props;
223 | return (
224 |
225 |
226 |
227 | );
228 | };
229 | ARPlaneScene.defaultProps = {
230 | ppm: 10 * 38, // 10 dpi,
231 | height: 1,
232 | width: 1
233 | };
234 | ARPlaneScene.propTypes = {
235 | ...ARPlane.propTypes,
236 | ...ARSKScene.propTypes,
237 | ppm: PropTypes.number
238 | };
239 | ARSign.propTypes = {
240 | ...ARPlaneScene.propTypes,
241 | text: PropTypes.string.isRequired
242 | };
243 | ARSign.defaultProps = {
244 | ...ARPlaneScene.defaultProps
245 | };
246 | export const ARSignNode = GeoNode(ARSign);
247 | export const ARPlaneSceneNode = GeoNode(ARPlaneSceneNode);
248 |
249 | export const ARNoSession = props => {
250 | return (
251 |
252 | {({ isStarted }) => {
253 | if (typeof isStarted == undefined)
254 | throw new Error(
255 | "ARNoSession must be a descendent of ARSessionProvider"
256 | );
257 | if (!isStarted) {
258 | return props.children;
259 | }
260 | return null;
261 | }}
262 |
263 | );
264 | };
265 | export const ARIsSession = props => {
266 | return (
267 |
268 | {({ isStarted }) => {
269 | if (typeof isStarted == undefined)
270 | throw new Error(
271 | "ARNoSession must be a descendent of ARSessionProvider"
272 | );
273 | if (isStarted) {
274 | return props.children;
275 | }
276 | return null;
277 | }}
278 |
279 | );
280 | };
281 | export const ARNoTracking = props => {
282 | return (
283 |
284 | {({ anchors }) => {
285 | if (!anchors || !Object.keys(anchors).length) {
286 | return props.children;
287 | }
288 | }}
289 |
290 | );
291 | };
292 | export const ARIsTracking = props => {
293 | return (
294 |
295 | {({ anchors }) => {
296 | if (anchors && Object.keys(anchors).length) {
297 | return props.children;
298 | }
299 | }}
300 |
301 | );
302 | };
303 |
304 | export const ARMeNode = props => {
305 | return (
306 |
307 | {({ position, orientation }) => {
308 | if (typeof orientation.x === "undefined") {
309 | return (
310 |
311 |
312 |
313 | );
314 | }
315 | return ;
316 | }}
317 |
318 | );
319 | };
320 |
321 | export class ARButton extends Component {
322 | state = {
323 | zPos: 0,
324 | color: "red"
325 | };
326 | componentWillMount() {
327 | this.setState({ color: this.props.color && "blue" });
328 | }
329 | render() {
330 | return (
331 |
332 | {
335 | this.setState({
336 | zPos: this.props.pressDepth,
337 | color: this.props.highlightColor
338 | });
339 | this.props.onPressIn && this.props.onPressIn();
340 | }}
341 | onPressOut={() => {
342 | this.setState({ zPos: 0, color: this.props.color });
343 | this.props.onPressOut && this.props.onPressOut();
344 | }}
345 | onPress={this.props.onPress}
346 | >
347 |
356 |
357 |
358 | );
359 | }
360 | }
361 | ARButton.defaultProps = {
362 | width: 1,
363 | height: 0.5,
364 | color: "blue",
365 | highlightColor: "purple",
366 | fontColor: "white",
367 | onPress: () => {},
368 | pressDepth: -0.2
369 | };
370 |
--------------------------------------------------------------------------------
/ios/react_native-arkit-swift-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import
4 | #import
5 | #import
6 | #import "SVGBezierPath.h"
7 |
--------------------------------------------------------------------------------
/ios/react_native-arkit-swift.xcodeproj/bob:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rhdeck/react-reality/0bb17e4fac6b2b521a7e2557004124d2d10f493f/ios/react_native-arkit-swift.xcodeproj/bob
--------------------------------------------------------------------------------
/ios/react_native-arkit-swift.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 48;
7 | objects = {
8 | /* Begin PBXBuildFile section */
9 | 712815C32026480B00C460CB /* ARExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 712815C22026480B00C460CB /* ARExtension.swift */; };
10 | 714545D92034E50D00E44E8D /* ARSceneManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 714545D82034E50D00E44E8D /* ARSceneManager.swift */; };
11 | 714545DB2034EA9000E44E8D /* ARMonoview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 714545DA2034EA9000E44E8D /* ARMonoview.swift */; };
12 | 714545DD2034EC9600E44E8D /* ARMonoviewManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 714545DC2034EC9600E44E8D /* ARMonoviewManager.swift */; };
13 | 714DC6E12050C55100BACAE8 /* ARPrimaryViewManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 714DC6E02050C55100BACAE8 /* ARPrimaryViewManager.swift */; };
14 | 714DC6E32050C56500BACAE8 /* ARSecondaryViewManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 714DC6E22050C56400BACAE8 /* ARSecondaryViewManager.swift */; };
15 | 719D02A3204DCC020096F3C1 /* ARSecondaryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 719D02A2204DCC020096F3C1 /* ARSecondaryView.swift */; };
16 | 719D02A5204DD2E90096F3C1 /* ARPrimaryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 719D02A4204DD2E90096F3C1 /* ARPrimaryView.swift */; };
17 | 71A4399620E654B50071F29C /* ARProjectedViewManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71A4399520E654B50071F29C /* ARProjectedViewManager.swift */; };
18 | 71A4399820E654C80071F29C /* ARProjectedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71A4399720E654C80071F29C /* ARProjectedView.swift */; };
19 | AAD78BA0AC6447529D3057BE /* rn-swift-bridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E00DCA45E7447438EF2917A /* rn-swift-bridge.m */; };
20 | /* End PBXBuildFile section */
21 |
22 | /* Begin PBXCopyFilesBuildPhase section */
23 | 71D8F37A1FB7A97B0000973C /* CopyFiles */ = {
24 | isa = PBXCopyFilesBuildPhase;
25 | buildActionMask = 2147483647;
26 | dstPath = "include/$(PRODUCT_NAME)";
27 | dstSubfolderSpec = 16;
28 | files = (
29 | );
30 | runOnlyForDeploymentPostprocessing = 0;
31 | };
32 | /* End PBXCopyFilesBuildPhase section */
33 |
34 | /* Begin PBXFileReference section */
35 | 712815C22026480B00C460CB /* ARExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ARExtension.swift; sourceTree = ""; };
36 | 714545D82034E50D00E44E8D /* ARSceneManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ARSceneManager.swift; sourceTree = ""; };
37 | 714545DA2034EA9000E44E8D /* ARMonoview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ARMonoview.swift; sourceTree = ""; };
38 | 714545DC2034EC9600E44E8D /* ARMonoviewManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ARMonoviewManager.swift; sourceTree = ""; };
39 | 714DC6E02050C55100BACAE8 /* ARPrimaryViewManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ARPrimaryViewManager.swift; sourceTree = ""; };
40 | 714DC6E22050C56400BACAE8 /* ARSecondaryViewManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ARSecondaryViewManager.swift; sourceTree = ""; };
41 | 719D02A2204DCC020096F3C1 /* ARSecondaryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ARSecondaryView.swift; sourceTree = ""; };
42 | 719D02A4204DD2E90096F3C1 /* ARPrimaryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ARPrimaryView.swift; sourceTree = ""; };
43 | 71A4399520E654B50071F29C /* ARProjectedViewManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ARProjectedViewManager.swift; sourceTree = ""; };
44 | 71A4399720E654C80071F29C /* ARProjectedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ARProjectedView.swift; sourceTree = ""; };
45 | 71D8F37C1FB7A97B0000973C /* libreact_native-arkit-swift.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libreact_native-arkit-swift.a"; sourceTree = BUILT_PRODUCTS_DIR; };
46 | 71D8F3881FB7AA9D0000973C /* react_native-arkit-swift-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "react_native-arkit-swift-Bridging-Header.h"; sourceTree = ""; };
47 | 8E00DCA45E7447438EF2917A /* rn-swift-bridge.m */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.c.objc; path = "rn-swift-bridge.m"; sourceTree = ""; };
48 | /* End PBXFileReference section */
49 |
50 | /* Begin PBXFrameworksBuildPhase section */
51 | 71D8F3791FB7A97B0000973C /* Frameworks */ = {
52 | isa = PBXFrameworksBuildPhase;
53 | buildActionMask = 2147483647;
54 | files = (
55 | );
56 | runOnlyForDeploymentPostprocessing = 0;
57 | };
58 | /* End PBXFrameworksBuildPhase section */
59 |
60 | /* Begin PBXGroup section */
61 | 712815D92029E82300C460CB /* Recovered References */ = {
62 | isa = PBXGroup;
63 | children = (
64 | );
65 | name = "Recovered References";
66 | sourceTree = "";
67 | };
68 | 71D8F3731FB7A97B0000973C = {
69 | isa = PBXGroup;
70 | children = (
71 | 71D8F37E1FB7A97B0000973C /* react_native-arkit-swift */,
72 | 71D8F37D1FB7A97B0000973C /* Products */,
73 | 8E00DCA45E7447438EF2917A /* rn-swift-bridge.m */,
74 | 71D8F3881FB7AA9D0000973C /* react_native-arkit-swift-Bridging-Header.h */,
75 | 712815D92029E82300C460CB /* Recovered References */,
76 | );
77 | sourceTree = "";
78 | };
79 | 71D8F37D1FB7A97B0000973C /* Products */ = {
80 | isa = PBXGroup;
81 | children = (
82 | 71D8F37C1FB7A97B0000973C /* libreact_native-arkit-swift.a */,
83 | );
84 | name = Products;
85 | sourceTree = "";
86 | };
87 | 71D8F37E1FB7A97B0000973C /* react_native-arkit-swift */ = {
88 | isa = PBXGroup;
89 | children = (
90 | 712815C22026480B00C460CB /* ARExtension.swift */,
91 | 714545DA2034EA9000E44E8D /* ARMonoview.swift */,
92 | 714545DC2034EC9600E44E8D /* ARMonoviewManager.swift */,
93 | 719D02A4204DD2E90096F3C1 /* ARPrimaryView.swift */,
94 | 714DC6E02050C55100BACAE8 /* ARPrimaryViewManager.swift */,
95 | 714545D82034E50D00E44E8D /* ARSceneManager.swift */,
96 | 719D02A2204DCC020096F3C1 /* ARSecondaryView.swift */,
97 | 714DC6E22050C56400BACAE8 /* ARSecondaryViewManager.swift */,
98 | 71A4399520E654B50071F29C /* ARProjectedViewManager.swift */,
99 | 71A4399720E654C80071F29C /* ARProjectedView.swift */,
100 | );
101 | path = "react_native-arkit-swift";
102 | sourceTree = "";
103 | };
104 | /* End PBXGroup section */
105 |
106 | /* Begin PBXNativeTarget section */
107 | 71D8F37B1FB7A97B0000973C /* react_native-arkit-swift */ = {
108 | isa = PBXNativeTarget;
109 | buildConfigurationList = 71D8F3851FB7A97B0000973C /* Build configuration list for PBXNativeTarget "react_native-arkit-swift" */;
110 | buildPhases = (
111 | 71D8F3781FB7A97B0000973C /* Sources */,
112 | 71D8F3791FB7A97B0000973C /* Frameworks */,
113 | 71D8F37A1FB7A97B0000973C /* CopyFiles */,
114 | );
115 | buildRules = (
116 | );
117 | dependencies = (
118 | );
119 | name = "react_native-arkit-swift";
120 | productName = "react_native-arkit-swift";
121 | productReference = 71D8F37C1FB7A97B0000973C /* libreact_native-arkit-swift.a */;
122 | productType = "com.apple.product-type.library.static";
123 | };
124 | /* End PBXNativeTarget section */
125 |
126 | /* Begin PBXProject section */
127 | 71D8F3741FB7A97B0000973C /* Project object */ = {
128 | isa = PBXProject;
129 | attributes = {
130 | LastUpgradeCheck = 930;
131 | ORGANIZATIONNAME = "Ray Deck";
132 | TargetAttributes = {
133 | 71D8F37B1FB7A97B0000973C = {
134 | CreatedOnToolsVersion = 9.2;
135 | LastSwiftMigration = 920;
136 | ProvisioningStyle = Automatic;
137 | };
138 | };
139 | };
140 | buildConfigurationList = 71D8F3771FB7A97B0000973C /* Build configuration list for PBXProject "react_native-arkit-swift" */;
141 | compatibilityVersion = "Xcode 8.0";
142 | developmentRegion = en;
143 | hasScannedForEncodings = 0;
144 | knownRegions = (
145 | en,
146 | );
147 | mainGroup = 71D8F3731FB7A97B0000973C;
148 | productRefGroup = 71D8F37D1FB7A97B0000973C /* Products */;
149 | projectDirPath = "";
150 | projectRoot = "";
151 | targets = (
152 | 71D8F37B1FB7A97B0000973C /* react_native-arkit-swift */,
153 | );
154 | };
155 | /* End PBXProject section */
156 |
157 | /* Begin PBXSourcesBuildPhase section */
158 | 71D8F3781FB7A97B0000973C /* Sources */ = {
159 | isa = PBXSourcesBuildPhase;
160 | buildActionMask = 2147483647;
161 | files = (
162 | 71A4399620E654B50071F29C /* ARProjectedViewManager.swift in Sources */,
163 | 712815C32026480B00C460CB /* ARExtension.swift in Sources */,
164 | 714DC6E12050C55100BACAE8 /* ARPrimaryViewManager.swift in Sources */,
165 | 719D02A5204DD2E90096F3C1 /* ARPrimaryView.swift in Sources */,
166 | 719D02A3204DCC020096F3C1 /* ARSecondaryView.swift in Sources */,
167 | 714545DB2034EA9000E44E8D /* ARMonoview.swift in Sources */,
168 | 71A4399820E654C80071F29C /* ARProjectedView.swift in Sources */,
169 | 714545D92034E50D00E44E8D /* ARSceneManager.swift in Sources */,
170 | 714DC6E32050C56500BACAE8 /* ARSecondaryViewManager.swift in Sources */,
171 | AAD78BA0AC6447529D3057BE /* rn-swift-bridge.m in Sources */,
172 | 714545DD2034EC9600E44E8D /* ARMonoviewManager.swift in Sources */,
173 | );
174 | runOnlyForDeploymentPostprocessing = 0;
175 | };
176 | /* End PBXSourcesBuildPhase section */
177 |
178 | /* Begin XCBuildConfiguration section */
179 | 71D8F3831FB7A97B0000973C /* Debug */ = {
180 | isa = XCBuildConfiguration;
181 | buildSettings = {
182 | ALWAYS_SEARCH_USER_PATHS = NO;
183 | CLANG_ANALYZER_NONNULL = YES;
184 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
185 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
186 | CLANG_CXX_LIBRARY = "libc++";
187 | CLANG_ENABLE_MODULES = YES;
188 | CLANG_ENABLE_OBJC_ARC = YES;
189 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
190 | CLANG_WARN_BOOL_CONVERSION = YES;
191 | CLANG_WARN_COMMA = YES;
192 | CLANG_WARN_CONSTANT_CONVERSION = YES;
193 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
194 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
195 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
196 | CLANG_WARN_EMPTY_BODY = YES;
197 | CLANG_WARN_ENUM_CONVERSION = YES;
198 | CLANG_WARN_INFINITE_RECURSION = YES;
199 | CLANG_WARN_INT_CONVERSION = YES;
200 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
201 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
202 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
203 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
204 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
205 | CLANG_WARN_STRICT_PROTOTYPES = YES;
206 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
207 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
208 | CLANG_WARN_UNREACHABLE_CODE = YES;
209 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
210 | CODE_SIGN_IDENTITY = "iPhone Developer";
211 | COPY_PHASE_STRIP = NO;
212 | DEBUG_INFORMATION_FORMAT = dwarf;
213 | ENABLE_STRICT_OBJC_MSGSEND = YES;
214 | ENABLE_TESTABILITY = YES;
215 | GCC_C_LANGUAGE_STANDARD = gnu11;
216 | GCC_DYNAMIC_NO_PIC = NO;
217 | GCC_NO_COMMON_BLOCKS = YES;
218 | GCC_OPTIMIZATION_LEVEL = 0;
219 | GCC_PREPROCESSOR_DEFINITIONS = (
220 | "DEBUG=1",
221 | "$(inherited)",
222 | );
223 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
224 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
225 | GCC_WARN_UNDECLARED_SELECTOR = YES;
226 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
227 | GCC_WARN_UNUSED_FUNCTION = YES;
228 | GCC_WARN_UNUSED_VARIABLE = YES;
229 | HEADER_SEARCH_PATHS = "";
230 | IPHONEOS_DEPLOYMENT_TARGET = 11.3;
231 | MTL_ENABLE_DEBUG_INFO = YES;
232 | ONLY_ACTIVE_ARCH = YES;
233 | SDKROOT = iphoneos;
234 | };
235 | name = Debug;
236 | };
237 | 71D8F3841FB7A97B0000973C /* Release */ = {
238 | isa = XCBuildConfiguration;
239 | buildSettings = {
240 | ALWAYS_SEARCH_USER_PATHS = NO;
241 | CLANG_ANALYZER_NONNULL = YES;
242 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
243 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
244 | CLANG_CXX_LIBRARY = "libc++";
245 | CLANG_ENABLE_MODULES = YES;
246 | CLANG_ENABLE_OBJC_ARC = YES;
247 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
248 | CLANG_WARN_BOOL_CONVERSION = YES;
249 | CLANG_WARN_COMMA = YES;
250 | CLANG_WARN_CONSTANT_CONVERSION = YES;
251 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
252 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
253 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
254 | CLANG_WARN_EMPTY_BODY = YES;
255 | CLANG_WARN_ENUM_CONVERSION = YES;
256 | CLANG_WARN_INFINITE_RECURSION = YES;
257 | CLANG_WARN_INT_CONVERSION = YES;
258 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
259 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
260 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
261 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
262 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
263 | CLANG_WARN_STRICT_PROTOTYPES = YES;
264 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
265 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
266 | CLANG_WARN_UNREACHABLE_CODE = YES;
267 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
268 | CODE_SIGN_IDENTITY = "iPhone Developer";
269 | COPY_PHASE_STRIP = NO;
270 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
271 | ENABLE_NS_ASSERTIONS = NO;
272 | ENABLE_STRICT_OBJC_MSGSEND = YES;
273 | GCC_C_LANGUAGE_STANDARD = gnu11;
274 | GCC_NO_COMMON_BLOCKS = YES;
275 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
276 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
277 | GCC_WARN_UNDECLARED_SELECTOR = YES;
278 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
279 | GCC_WARN_UNUSED_FUNCTION = YES;
280 | GCC_WARN_UNUSED_VARIABLE = YES;
281 | HEADER_SEARCH_PATHS = "";
282 | IPHONEOS_DEPLOYMENT_TARGET = 11.3;
283 | MTL_ENABLE_DEBUG_INFO = NO;
284 | SDKROOT = iphoneos;
285 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
286 | VALIDATE_PRODUCT = YES;
287 | };
288 | name = Release;
289 | };
290 | 71D8F3861FB7A97B0000973C /* Debug */ = {
291 | isa = XCBuildConfiguration;
292 | buildSettings = {
293 | CLANG_ENABLE_MODULES = YES;
294 | CODE_SIGN_STYLE = Automatic;
295 | DEVELOPMENT_TEAM = 3UK2WGC8YX;
296 | FRAMEWORK_SEARCH_PATHS = (
297 | "$(inherited)",
298 | "/Users/ray/Documents/artesta/ios/Pods/**",
299 | "/Users/ray/Documents/artestb/ios/Pods/**",
300 | );
301 | HEADER_SEARCH_PATHS = (
302 | "$(inherited)",
303 | "$(SRCROOT)/../../../ios/Pods/**",
304 | "/Users/ray/Documents/artesta/ios/Pods/**",
305 | "/Users/ray/Documents/artestb/ios/Pods/**",
306 | );
307 | IPHONEOS_DEPLOYMENT_TARGET = 11.3;
308 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
309 | OTHER_LDFLAGS = "-ObjC";
310 | PRODUCT_NAME = "$(TARGET_NAME)";
311 | SKIP_INSTALL = YES;
312 | SWIFT_OBJC_BRIDGING_HEADER = "react_native-arkit-swift-Bridging-Header.h";
313 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
314 | SWIFT_VERSION = 3.0;
315 | TARGETED_DEVICE_FAMILY = "1,2";
316 | };
317 | name = Debug;
318 | };
319 | 71D8F3871FB7A97B0000973C /* Release */ = {
320 | isa = XCBuildConfiguration;
321 | buildSettings = {
322 | CLANG_ENABLE_MODULES = YES;
323 | CODE_SIGN_STYLE = Automatic;
324 | DEVELOPMENT_TEAM = 3UK2WGC8YX;
325 | FRAMEWORK_SEARCH_PATHS = (
326 | "$(inherited)",
327 | "/Users/ray/Documents/artesta/ios/Pods/**",
328 | "/Users/ray/Documents/artestb/ios/Pods/**",
329 | );
330 | HEADER_SEARCH_PATHS = (
331 | "$(inherited)",
332 | "$(SRCROOT)/../../../ios/Pods/**",
333 | "/Users/ray/Documents/artesta/ios/Pods/**",
334 | "/Users/ray/Documents/artestb/ios/Pods/**",
335 | );
336 | IPHONEOS_DEPLOYMENT_TARGET = 11.3;
337 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
338 | OTHER_LDFLAGS = "-ObjC";
339 | PRODUCT_NAME = "$(TARGET_NAME)";
340 | SKIP_INSTALL = YES;
341 | SWIFT_OBJC_BRIDGING_HEADER = "react_native-arkit-swift-Bridging-Header.h";
342 | SWIFT_VERSION = 3.0;
343 | TARGETED_DEVICE_FAMILY = "1,2";
344 | };
345 | name = Release;
346 | };
347 | /* End XCBuildConfiguration section */
348 |
349 | /* Begin XCConfigurationList section */
350 | 71D8F3771FB7A97B0000973C /* Build configuration list for PBXProject "react_native-arkit-swift" */ = {
351 | isa = XCConfigurationList;
352 | buildConfigurations = (
353 | 71D8F3831FB7A97B0000973C /* Debug */,
354 | 71D8F3841FB7A97B0000973C /* Release */,
355 | );
356 | defaultConfigurationIsVisible = 0;
357 | defaultConfigurationName = Release;
358 | };
359 | 71D8F3851FB7A97B0000973C /* Build configuration list for PBXNativeTarget "react_native-arkit-swift" */ = {
360 | isa = XCConfigurationList;
361 | buildConfigurations = (
362 | 71D8F3861FB7A97B0000973C /* Debug */,
363 | 71D8F3871FB7A97B0000973C /* Release */,
364 | );
365 | defaultConfigurationIsVisible = 0;
366 | defaultConfigurationName = Release;
367 | };
368 | /* End XCConfigurationList section */
369 | };
370 | rootObject = 71D8F3741FB7A97B0000973C /* Project object */;
371 | }
372 |
--------------------------------------------------------------------------------
/ios/react_native-arkit-swift/ARExtension.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import SceneKit
3 | import SpriteKit
4 | typealias jsonType = [String:Any]
5 | @objc extension RCTConvert {
6 | @objc class func SCNMaterial(_ json:jsonType) -> SCNMaterial {
7 | let m:SCNMaterial = SceneKit.SCNMaterial()
8 | setMaterialProperties(m, properties: json)
9 | return m
10 | }
11 | @objc class func SCNVector3(_ json:jsonType) -> SCNVector3 {
12 | let x = json["x"] as? Double ?? 0
13 | let y = json["y"] as? Double ?? 0
14 | let z = json["z"] as? Double ?? 0
15 | return SceneKit.SCNVector3(x, y, z)
16 | }
17 |
18 | @objc class func SCNVector4(_ json: jsonType) -> SCNVector4 {
19 | let x = json["x"] as? Double ?? 0
20 | let y = json["y"] as? Double ?? 0
21 | let z = json["z"] as? Double ?? 0
22 | let w = json["w"] as? Double ?? 0
23 | return SceneKit.SCNVector4(x, y, z, w)
24 | }
25 | @objc class func SCNNode(_ json: jsonType) -> SCNNode {
26 | let n = SceneKit.SCNNode()
27 | if let name = json["id"] as? String {
28 | n.name = name
29 | }
30 | setNodeProperties(n, properties: json)
31 | return n
32 | }
33 | @objc class func SCNBox(_ json:jsonType)-> SCNBox {
34 | guard
35 | let w = json["width"] as? CGFloat,
36 | let h = json["height"] as? CGFloat,
37 | let l = json["length"] as? CGFloat
38 | else { return SceneKit.SCNBox() }
39 | let chamfer = json["chamfer"] as? CGFloat ?? 0
40 | let g = SceneKit.SCNBox(width: w, height: h, length: l, chamferRadius: chamfer)
41 | return g
42 | }
43 | @objc class func SCNCapsule(_ json: jsonType) -> SCNCapsule {
44 | guard
45 | let tr = json["capR"] as? CGFloat,
46 | let h = json["height"] as? CGFloat
47 | else { return SceneKit.SCNCapsule() }
48 | let g = SceneKit.SCNCapsule(capRadius: tr, height: h)
49 | return g
50 | }
51 | @objc class func SCNCone(_ json:jsonType)-> SCNCone {
52 | guard
53 | let tr = json["topR"] as? CGFloat,
54 | let br = json["bottomR"] as? CGFloat,
55 | let h = json["height"] as? CGFloat
56 | else { return SceneKit.SCNCone() }
57 | let g = SceneKit.SCNCone(topRadius: tr, bottomRadius: br, height: h)
58 | return g
59 | }
60 | @objc class func SCNCylinder(_ json:jsonType)-> SCNCylinder {
61 | guard
62 | let r = json["radius"] as? CGFloat,
63 | let h = json["height"] as? CGFloat
64 | else { return SceneKit.SCNCylinder() }
65 | let g = SceneKit.SCNCylinder(radius: r, height: h)
66 | return g
67 | }
68 | @objc class func SCNPlane(_ json: jsonType) -> SCNPlane {
69 | guard
70 | let w = json["width"] as? CGFloat,
71 | let h = json["height"] as? CGFloat
72 | else { return SceneKit.SCNPlane() }
73 | let g = SceneKit.SCNPlane(width: w, height: h)
74 | if let cr = json["cornerRadius"] as? CGFloat { g.cornerRadius = cr }
75 | if let i = json["cornerSegmentCount"] as? Int { g.cornerSegmentCount = i }
76 | if let i = json["widthSegmentCount"] as? Int { g.widthSegmentCount = i }
77 | if let i = json["heightSegmentCount"] as? Int { g.heightSegmentCount = i }
78 | return g
79 | }
80 | @objc class func SCNPyramid(_ json: jsonType) -> SCNPyramid {
81 | guard
82 | let w = json["width"] as? CGFloat,
83 | let h = json["height"] as? CGFloat,
84 | let l = json["length"] as? CGFloat
85 | else { return SceneKit.SCNPyramid() }
86 | let g = SceneKit.SCNPyramid(width: w, height: h, length: l)
87 | return g
88 | }
89 | @objc class func SCNSphere(_ json:jsonType)-> SCNSphere {
90 | guard
91 | let r = json["radius"] as? CGFloat
92 | else { return SceneKit.SCNSphere() }
93 | let g = SceneKit.SCNSphere(radius: r)
94 | return g
95 | }
96 | @objc class func SCNTorus(_ json: jsonType) -> SCNTorus {
97 | guard
98 | let tr = json["ringR"] as? CGFloat,
99 | let br = json["pipeR"] as? CGFloat
100 | else { return SceneKit.SCNTorus() }
101 | let g = SceneKit.SCNTorus(ringRadius: tr, pipeRadius: br)
102 | return g
103 | }
104 | @objc class func SCNTube(_ json: jsonType) -> SCNTube {
105 | guard
106 | let tr = json["innerR"] as? CGFloat,
107 | let br = json["outerR"] as? CGFloat,
108 | let h = json["height"] as? CGFloat
109 | else { return SceneKit.SCNTube() }
110 | let g = SceneKit.SCNTube(innerRadius: tr, outerRadius: br, height: h)
111 | return g
112 | }
113 | @objc class func SCNText(_ json: jsonType) -> SCNText {
114 | let baseFontSize:CGFloat = 12.0;
115 | let text = json["text"] as? String ?? "(null)"
116 | let depth = json["depth"] as? CGFloat ?? 0.0
117 | let fontSize = json["size"] as? CGFloat ?? baseFontSize
118 | let size:CGFloat = fontSize / baseFontSize;
119 | let st = SceneKit.SCNText(string: text, extrusionDepth: (depth / size))
120 | st.flatness = 0.1
121 | var f = UIFont.systemFont(ofSize: baseFontSize)
122 | if let fontName = json["fontName"] as? String {
123 | if let tf = UIFont(name: fontName, size: baseFontSize) { f = tf }
124 | }
125 | if let cf = json["chamfer"] as? CGFloat { st.chamferRadius = cf / size }
126 | st.font = f
127 | return st
128 | }
129 | @objc class func SCNLight(_ json: jsonType) -> SCNLight {
130 | let l = SceneKit.SCNLight()
131 | setLightProperties(l, properties: json)
132 | return l
133 | }
134 | @objc class func SCNShape(_ json: jsonType) -> SCNShape {
135 | guard
136 | let svg = json["pathSvg"] as? String
137 | else { return SceneKit.SCNShape()}
138 | let extrusion = json["extrusion"] as? CGFloat ?? 0.0
139 | let path = svgStringToBezier(svg)
140 | if let f = json["pathFlatness"] as? CGFloat { path.flatness = f }
141 | let uib = UIBezierPath(cgPath: path.cgPath)
142 | let g = SceneKit.SCNShape(path: uib, extrusionDepth: extrusion)
143 | if let e = json["chamferMode"] as? SCNChamferMode { g.chamferMode = e }
144 | if let f = json["chamferRadius"] as? CGFloat { g.chamferRadius = f }
145 | if let csvg = json["chamferProfilePathSvg"] as? String {
146 | let cpath = svgStringToBezier(csvg)
147 | if let f = json["chamferProfilePathFlatness"] as? CGFloat { cpath.flatness = f }
148 | let bb:CGRect = cpath.bounds
149 | if bb.size.width > 0 && bb.size.height > 0 {
150 | let scalex = 1 / bb.size.width
151 | let scaley = 1 / bb.size.height
152 | let transform = CGAffineTransform(scaleX: scalex, y: scaley)
153 | cpath.apply(transform)
154 | let cgpath = cpath.cgPath
155 | let upath = UIBezierPath(cgPath: cgpath)
156 | // g.chamferProfile = upath //Disabled chamfer for now because it keeps crashing @TODO
157 | }
158 | }
159 | return g
160 | }
161 | @objc class func SKLabelNode(_ json: jsonType) -> SKLabelNode {
162 | let skln = SpriteKit.SKLabelNode()
163 | doUpdateSKLabelNode(skln, json: json);
164 | skln.yScale = -1
165 | return skln
166 | }
167 | @objc class func SKScene(_ json: jsonType) -> SKScene {
168 | let s = SpriteKit.SKScene()
169 | doUpdateSKScene(s, json: json)
170 | return s
171 | }
172 | @objc class func SKVideoNode(_ json: jsonType) -> SKVideoNode {
173 | var svn: SpriteKit.SKVideoNode?
174 | if let s = json["url"] as? String {
175 | if let u = URL(string: s) {
176 | svn = SpriteKit.SKVideoNode(url: u)
177 | }
178 | } else if let s = json["path"] as? String {
179 | let u = URL(fileURLWithPath: s)
180 | NSLog("Loading video from path " + s)
181 | svn = SpriteKit.SKVideoNode(url: u)
182 | }
183 | if svn == nil { svn = SpriteKit.SKVideoNode() ; return svn! }
184 | doUpdateSKVideoNode(svn!, json: json)
185 | return svn!
186 | }
187 | }
188 | func doUpdateSKVideoNode(_ node:SKVideoNode, json: jsonType) {
189 | doUpdateSKNode(node, json: json)
190 | let h = json["height"] as? Double ?? 100
191 | let w = json["width"] as? Double ?? 100
192 | NSLog("Updating SKVideo to height " + String(h) + " and width " + String(w))
193 | node.size = CGSize(width: CGFloat(w), height: CGFloat(h))
194 | if json["isPlaying"] as? Bool ?? false {
195 | NSLog("Starting video...")
196 | DispatchQueue.main.async() {
197 | node.play()
198 | }
199 | } else {
200 | DispatchQueue.main.async() {
201 | node.pause()
202 | }
203 | }
204 | }
205 | func doUpdateSKNode(_ node: SKNode, json: jsonType) {
206 | if let s = json["name"] as? String { node.name = s }
207 | if let j = json["position"] as? jsonType {
208 | let x = j["x"] as? Double ?? 0
209 | let y = j["y"] as? Double ?? 0
210 | node.position = CGPoint(x: x, y: y)
211 | }
212 | }
213 | func doUpdateSKScene(_ scene:SKScene, json:jsonType) {
214 | if let s = json["name"] as? String { scene.name = s }
215 | if let i = json["color"] { scene.backgroundColor = RCTConvert.uiColor(i) }
216 | let h = json["height"] as? Double ?? 100
217 | let w = json["width"] as? Double ?? 100
218 | NSLog("Updating scene to height of " + String(h) + " and width of " + String(w) )
219 | print(json)
220 | scene.size = CGSize(width: CGFloat(w), height: CGFloat(h))
221 | }
222 | func doUpdateSKLabelNode(_ skln:SKLabelNode, json: jsonType) {
223 | doUpdateSKNode(skln, json: json)
224 | if let s = json["text"] as? String { skln.text = s }
225 | skln.numberOfLines = json["lines"] as? Int ?? 1
226 | switch json["lineBreak"] as? String {
227 | case "char": skln.lineBreakMode = .byCharWrapping
228 | case "ellipsis": skln.lineBreakMode = .byTruncatingTail
229 | case "word": skln.lineBreakMode = .byWordWrapping
230 | case nil: skln.lineBreakMode = skln.numberOfLines == 1 ? .byTruncatingTail : .byWordWrapping
231 | default:skln.lineBreakMode = skln.numberOfLines == 1 ? .byTruncatingTail : .byWordWrapping
232 | }
233 | skln.lineBreakMode = .byWordWrapping
234 | if let s = json["fontName"] as? String { skln.fontName = s }
235 | if let d = json["fontSize"] as? Double { skln.fontSize = CGFloat(d) }
236 | if let c = json["fontColor"] { skln.fontColor = RCTConvert.uiColor(c) }
237 | skln.verticalAlignmentMode = .top
238 | if let s = json["verticalAlignment"] as? String {
239 | switch s {
240 | case "top":
241 | skln.verticalAlignmentMode = .top
242 | case "baseline":
243 | skln.verticalAlignmentMode = .baseline
244 | case "bottom":
245 | skln.verticalAlignmentMode = .bottom
246 | case "center":
247 | skln.verticalAlignmentMode = .center
248 | default:
249 | print("Invalid verticalalignmentmode passed: " + s)
250 | }
251 | }
252 | skln.horizontalAlignmentMode = .left
253 | if let s = json["horizontalAlignment"] as? String {
254 | switch s {
255 | case "left":
256 | skln.horizontalAlignmentMode = .left
257 | case "center":
258 | skln.horizontalAlignmentMode = .center
259 | case "right":
260 | skln.horizontalAlignmentMode = .right
261 | default:
262 | print("Invalid horizontalalignmentmode passed " + s)
263 | }
264 | }
265 | if let d = json["width"] as? Double { skln.preferredMaxLayoutWidth = CGFloat(d) }
266 | if json["allowScaling"] as? Bool ?? true {
267 | let scalingFactor = skln.preferredMaxLayoutWidth / skln.frame.width
268 | if(scalingFactor < 1) {
269 | skln.fontSize = skln.fontSize * scalingFactor
270 | }
271 | }
272 | }
273 | func addMaterials(_ g:SCNGeometry, json: jsonType, sides:Int) {
274 | guard let mj = json["material"] as? jsonType else { return }
275 | let m = RCTConvert.SCNMaterial(mj)
276 | var ms:[SceneKit.SCNMaterial] = [];
277 | for _ in 1...sides {
278 | ms.append(m)
279 | }
280 | g.materials = ms
281 | }
282 | func setMaterialProperties(_ material:SCNMaterial, properties: jsonType) {
283 | material.isDoubleSided = properties["doubleSided"] as? Bool ?? true
284 | if let i = properties["blendMode"] as? SCNBlendMode { material.blendMode = i }
285 | if let lm = properties["lightingModel"] as? SCNMaterial.LightingModel { material.lightingModel = lm }
286 | if let f = properties["transparency"] as? CGFloat { material.transparency = f}
287 | if let f = properties["metalness"] as? Double { material.lightingModel = .physicallyBased; material.metalness.contents = f}
288 | if let f = properties["roughness"] as? Double { material.lightingModel = .physicallyBased; material.roughness.contents = f}
289 | if let x = properties["shaders"] as? [SCNShaderModifierEntryPoint: String] { material.shaderModifiers = x}
290 | if let b = properties["writesToDepthBuffer"] as? Bool { material.writesToDepthBuffer = b }
291 | if let i = properties["colorBufferWriteMask"] as? SCNColorMask { material.colorBufferWriteMask = i}
292 | if let i = properties["fillMode"] as? SCNFillMode { material.fillMode = i}
293 | if let b = properties["litPerPixel"] as? Bool { material.isLitPerPixel = b}
294 | material.transparencyMode = .aOne
295 | }
296 | func setNodeProperties(_ node:SCNNode, properties: jsonType) {
297 | if let i = properties["categoryBitMask"] as? Int { node.categoryBitMask = i }
298 | if let i = properties["renderingOrder"] as? Int { node.renderingOrder = i }
299 | if let b = properties["castsShadow"] as? Bool { node.castsShadow = b }
300 | if let d = properties["position"] as? jsonType { node.position = RCTConvert.SCNVector3(d) }
301 | if let f = properties["scale"] as? Double { node.scale = SCNVector3(f, f, f) }
302 | if let d = properties["eulerAngles"] as? jsonType { node.eulerAngles = RCTConvert.SCNVector3(d) }
303 | if let d = properties["orientation"] as? jsonType { node.orientation = RCTConvert.SCNVector4(d) }
304 | if let d = properties["rotation"] as? jsonType { node.rotation = RCTConvert.SCNVector4(d) }
305 | if let f = properties["opacity"] as? CGFloat { node.opacity = f }
306 | }
307 | func setMaterialPropertyContents(_ properties: jsonType, materialProperty: SCNMaterialProperty) {
308 | if let path = properties["path"] { materialProperty.contents = path }
309 | else if let color = properties["color"] { materialProperty.contents = RCTConvert.uiColor(color) }
310 | if let intensity = properties["intensity"] as? CGFloat { materialProperty.intensity = intensity }
311 | }
312 | func setShapeProperties(_ g:SCNGeometry, properties: jsonType) {
313 | properties.forEach() {k, v in
314 | guard
315 | let vs = v as? String,
316 | !specialShapeProperties.contains(vs),
317 | let f = Float(vs)
318 | else { return }
319 | g.setValue(f, forKey: k)
320 | }
321 | guard let shapeGeometry = g as? SCNShape else { return }
322 | if let s = properties["pathSvg"] as? String {
323 | let path = svgStringToBezier(s)
324 | if let f = properties["pathFlatness"] as? CGFloat { path.flatness = f }
325 | shapeGeometry.path = path
326 | }
327 | if let d = properties["chamferProfilesPathSvg"] as? jsonType { setChamferProfilePathSvg(shapeGeometry, properties: d) }
328 | }
329 | func svgStringToBezier(_ path:String) -> SVGBezierPath {
330 | NSLog("Starting with path " + path)
331 | guard let paths:[SVGBezierPath] = SVGBezierPath.paths(fromSVGString: path) as? [SVGBezierPath] else { return SVGBezierPath() }
332 | NSLog("I am continuing with interpreted paths: " + String(paths.count))
333 | let fullPath = paths[0];
334 | NSLog("Fullpath")
335 | NSLog(fullPath.svgRepresentation)
336 | NSLog("that's all she wrote")
337 | if(paths.count > 1) {
338 | for x in 2...paths.count {
339 | let p = paths[x-1]
340 | fullPath.append(p)
341 | }
342 | }
343 | return fullPath
344 | }
345 | func setChamferProfilePathSvg(_ g:SCNShape, properties: jsonType) {
346 | guard let svg = properties["chamferProfilePathSvg"] as? String else { return }
347 | let path = svgStringToBezier(svg)
348 | let cgpath = path.cgPath
349 | let upath = UIBezierPath(cgPath: cgpath)
350 | if let f = properties["chamferProfilePathFlatness"] as? CGFloat { upath.flatness = f }
351 | let bb:CGRect = upath.bounds
352 | if bb.size.width > 0 && bb.size.height > 0 {
353 | let scalex = 1 / bb.size.width
354 | let scaley = 1 / bb.size.height
355 | let transform = CGAffineTransform(scaleX: scalex, y: scaley)
356 | upath.apply(transform)
357 | g.chamferProfile = upath
358 | }
359 | }
360 | func setLightProperties(_ light:SCNLight, properties: jsonType) {
361 | if let i = properties["lightCategoryBitMask"] as? Int { light.categoryBitMask = i }
362 | if let e = properties["type"] as? SCNLight.LightType { light.type = e }
363 | if let c = properties["color"], let rc = RCTConvert.cgColor(c) { light.color = rc }
364 | if let f = properties["temperature"] as? CGFloat { light.temperature = f }
365 | if let f = properties["intensity"] as? CGFloat { light.intensity = f }
366 | if let f = properties["attenuationStartDistance"] as? CGFloat { light.attenuationStartDistance = f}
367 | if let f = properties["attenuationEndDistance"] as? CGFloat { light.attenuationEndDistance = f}
368 | if let f = properties["spotInnerAngle"] as? CGFloat { light.spotInnerAngle = f}
369 | if let f = properties["spotOuterAngle"] as? CGFloat { light.spotOuterAngle = f}
370 | if let b = properties["castsShadow"] as? Bool { light.castsShadow = b }
371 | if let f = properties["shadowRadius"] as? CGFloat { light.shadowRadius = f }
372 | if let c = properties["shadowColor"], let rc = RCTConvert.cgColor(c) { light.shadowColor = rc }
373 | if let i = properties["shadowSampleCount"] as? Int { light.shadowSampleCount = i }
374 | if let f = properties["shadowBias"] as? CGFloat { light.shadowBias = f }
375 | if let e = properties["shadowMode"] as? SCNShadowMode { light.shadowMode = e }
376 | if let f = properties["orthographicScale"] as? CGFloat { light.orthographicScale = f }
377 | if let f = properties["zFar"] as? CGFloat { light.zFar = f }
378 | if let f = properties["zNear"] as? CGFloat { light.orthographicScale = f }
379 | }
380 | let specialShapeProperties:Set = [
381 | "pathSvg",
382 | "chamferProfilePathSvg"
383 | ]
384 | func vector3ToJson(_ v:SCNVector3) -> jsonType {
385 | return ["x": v.x, "y": v.y, "z": v.z]
386 | }
387 | func vector_float3ToJson(_ v:vector_float3) -> jsonType {
388 | return ["x": v.x, "y": v.y, "z": v.z]
389 | }
390 | func vector4ToJson(_ v:SCNVector4) -> jsonType {
391 | return ["x": v.x, "y": v.y, "z": v.z, "w": v.w]
392 | }
393 | func vector_float4ToVector3(_ v:vector_float4) -> SCNVector3 {
394 | return SCNVector3(v.x, v.y, v.z)
395 | }
396 |
--------------------------------------------------------------------------------
/ios/react_native-arkit-swift/ARMonoview.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import ARKit
3 | @objc(ARMonoView)
4 | class ARMonoView: UIView, ARSCNViewDelegate {
5 | var arview: ARSCNView?
6 | var _preview:Bool = true
7 | var cachedPreview: Any?
8 | var _debugMode: Bool = false
9 | @objc var preview:Bool {
10 | get {
11 | return _preview
12 | }
13 | set(newVal) {
14 | if cachedPreview == nil {
15 | cachedPreview = arview?.scene.background.contents
16 | }
17 | _preview = newVal
18 | if(_preview) {
19 | arview?.scene.background.contents = cachedPreview
20 |
21 | } else {
22 | arview?.scene.background.contents = UIColor.black
23 | }
24 | }
25 | }
26 | @objc var debugMode: Bool {
27 | get {
28 | return _debugMode
29 | }
30 | set(newVal) {
31 | _debugMode = newVal
32 | arview?.debugOptions = newVal ? .showFeaturePoints : .init(rawValue: 0)
33 | }
34 | }
35 | func start() -> ARMonoView {
36 | if Thread.isMainThread {
37 | let a = ARSCNView()
38 | arview = a
39 | a.delegate = self
40 | guard let sm = ARSceneManager.sharedInstance else { return self }
41 | a.session.delegate = sm
42 | sm.scene = a.scene
43 | sm.session = a.session
44 | sm.pv = a
45 | a.automaticallyUpdatesLighting = true
46 | a.autoenablesDefaultLighting = true
47 | addSubview(a)
48 | sm.doResume()
49 | }
50 | return self
51 | }
52 | override func layoutSubviews() {
53 | super.layoutSubviews()
54 | arview?.frame = self.bounds
55 | }
56 | func handleTap(point: CGPoint, resolve:RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
57 | guard let v = arview else { reject("no_view", "No AR View", nil); return }
58 | let r = v.hitTest(point, options: nil)
59 | let m = r.map() { h in
60 | return h.node.name
61 | }
62 | resolve(["nodes": m]);
63 | }
64 | func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
65 | guard let scene = ARSceneManager.sharedInstance else { return }
66 | scene.updateAnchor(anchor, withNode: node)
67 | }
68 | func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
69 | guard let scene = ARSceneManager.sharedInstance else { return }
70 | scene.addAnchor(anchor, withNode: node)
71 |
72 | }
73 | func renderer(_ renderer: SCNSceneRenderer, didRenderScene scene: SCNScene, atTime time: TimeInterval) {
74 | guard let scene = ARSceneManager.sharedInstance else { return }
75 | if let pov = renderer.pointOfView { scene.updatePOV(pov) }
76 | scene.updateRegisteredViews()
77 |
78 | }
79 |
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/ios/react_native-arkit-swift/ARMonoviewManager.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | @objc(ARMonoViewManager)
3 | class ARMonoViewManager:RCTViewManager {
4 | var v: ARMonoView?
5 | override func view() -> ARMonoView {
6 | v = (ARMonoView()).start()
7 | return v!
8 | }
9 | override class func requiresMainQueueSetup() -> Bool {
10 | return false
11 | }
12 | @objc func doTap(_ x: Double, y: Double, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
13 | guard let v = self.v else { reject("no_view", "No View loaded", nil); return }
14 | v.handleTap(point: CGPoint(x: CGFloat(x), y: CGFloat(y)), resolve:resolve, reject: reject)
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ios/react_native-arkit-swift/ARPrimaryView.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import ARKit
3 |
4 | @objc(ARPrimaryView)
5 | class ARPrimaryView: UIView, ARSCNViewDelegate {
6 | var arview: ARSCNView?
7 | var pview: SCNView?
8 | var onStart:RCTBubblingEventBlock?
9 | @objc var interPupilaryDistance:Float = 0.066
10 | @objc var holoOffsetY: Float = 0.08
11 | @objc var holoOffsetZ: Float = -0.08
12 | @objc var holoOffsetX: Float = 0.033
13 | @objc var fieldOfView: Float = 60
14 | func start() -> ARPrimaryView {
15 | if Thread.isMainThread {
16 | let a = ARSCNView()
17 | let p = SCNView()
18 | pview = p
19 | p.scene = a.scene
20 | p.isPlaying = true
21 | p.autoenablesDefaultLighting = true
22 | arview = a
23 | a.delegate = self
24 | guard let sm = ARSceneManager.sharedInstance else { return self }
25 | a.session.delegate = sm
26 | sm.addScene(a.scene)
27 | sm.session = a.session
28 | p.backgroundColor = UIColor.yellow
29 | p.scene?.background.contents = UIColor.black
30 | a.autoenablesDefaultLighting = true
31 | addSubview(a)
32 | addSubview(p)
33 | sm.doResume()
34 | self.clipsToBounds = true
35 | } else {
36 | DispatchQueue.main.async(){
37 | let _ = self.start();
38 | }
39 | }
40 | return self
41 | }
42 | override func layoutSubviews() {
43 | super.layoutSubviews()
44 | pview?.frame = self.bounds
45 | arview?.frame = self.bounds
46 | arview?.isHidden = true
47 | }
48 | func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
49 | DispatchQueue.main.async() {
50 | guard
51 | let sm = ARSceneManager.sharedInstance,
52 | let sv = sm.secondaryView,
53 | let ppv = self.pview,
54 | let pv = self.arview,
55 | let PVpointOfView = pv.pointOfView?.clone()
56 | else { return }
57 |
58 | let orientation : SCNQuaternion = PVpointOfView.orientation
59 | let YPos = SCNQToSCN3(orientation, v:SCNVector3Make( 0, 1, 0))
60 | PVpointOfView.position = applyOffset(v: PVpointOfView.position, withV: YPos, byScalar: self.holoOffsetY)
61 | let ZPos = SCNQToSCN3(orientation, v: SCNVector3Make(0,0,1))
62 | PVpointOfView.position = applyOffset(v: PVpointOfView.position, withV: ZPos , byScalar: self.holoOffsetZ)
63 | let XPos = SCNQToSCN3(orientation, v:SCNVector3Make( 1, 0, 0))
64 | PVpointOfView.position = applyOffset(v: PVpointOfView.position, withV: XPos, byScalar: self.holoOffsetX)
65 | PVpointOfView.camera?.fieldOfView = CGFloat(self.fieldOfView)
66 | ppv.pointOfView = PVpointOfView
67 | // Determine Adjusted Position for Right Eye
68 | let SVPointOfView = PVpointOfView.clone()
69 | SVPointOfView.position = applyOffset(v: SVPointOfView.position, withV: XPos, byScalar:1.0 * self.interPupilaryDistance)
70 | SVPointOfView.camera?.fieldOfView = CGFloat(self.fieldOfView)
71 | sv.pointOfView = SVPointOfView
72 | if let pov = renderer.pointOfView { sm.updatePOV(pov) }
73 | sm.updateRegisteredViews()
74 | }
75 | }
76 | func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
77 | guard let scene = ARSceneManager.sharedInstance else { return }
78 | scene.updateAnchor(anchor, withNode: node)
79 | }
80 | func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
81 | guard let scene = ARSceneManager.sharedInstance else { return }
82 | scene.addAnchor(anchor, withNode: node)
83 |
84 | }
85 | func renderer(_ renderer: SCNSceneRenderer, didRemove node: SCNNode, for anchor: ARAnchor) {
86 | guard let scene = ARSceneManager.sharedInstance else { return }
87 | scene.removeAnchor(anchor, withNode: node)
88 | }
89 | }
90 | func GLK3ToSCN3(_ g:GLKVector3) -> SCNVector3 {
91 | return SCNVector3Make(g.x, g.y, g.z)
92 | }
93 | func SCN3ToGLK3(_ s:SCNVector3) -> GLKVector3 {
94 | return GLKVector3Make(s.x, s.y, s.z)
95 | }
96 | func GQToSCN3(_ q: GLKQuaternion, v: GLKVector3) -> SCNVector3 {
97 | let gv = GLKQuaternionRotateVector3(q, v)
98 | return GLK3ToSCN3(gv)
99 | }
100 | func SCNQToGQ(_ q: SCNQuaternion) -> GLKQuaternion {
101 | return GLKQuaternionMake(q.x, q.y, q.z, q.w);
102 | }
103 | func SCNQToSCN3(_ q: SCNQuaternion, v: SCNVector3) -> SCNVector3 {
104 | let gq = SCNQToGQ(q)
105 | return GQToSCN3(gq, v: SCN3ToGLK3(v));
106 | }
107 | func applyOffset(v: SCNVector3, withV:SCNVector3, byScalar: Float) -> SCNVector3 {
108 | var v2 = SCNVector3Make(v.x, v.y, v.z)
109 | v2.x += withV.x * byScalar
110 | v2.y += withV.y * byScalar
111 | v2.z += withV.z * byScalar
112 | return v2
113 | }
114 |
--------------------------------------------------------------------------------
/ios/react_native-arkit-swift/ARPrimaryViewManager.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | @objc(ARPrimaryViewManager)
3 | class ARPrimaryViewManager : RCTViewManager {
4 | override func view() -> ARPrimaryView {
5 | return (ARPrimaryView()).start()
6 | }
7 | override class func requiresMainQueueSetup() -> Bool {
8 | return false
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/ios/react_native-arkit-swift/ARProjectedView.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | @objc(ARProjectedView)
3 | class ARProjectedView: UIView {
4 | var _parentNode:String?
5 | @objc var parentNode:String? {
6 | get { return _parentNode }
7 | set(newNode) {
8 | _parentNode = newNode
9 | guard let s = ARSceneManager.sharedInstance else { return }
10 | s.registerView(newNode, view: self)
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ios/react_native-arkit-swift/ARProjectedViewManager.swift:
--------------------------------------------------------------------------------
1 |
2 | import Foundation
3 | @objc(ARProjectedViewManager)
4 | class ARProjectedViewManager: RCTViewManager {
5 | override func view() -> ARProjectedView {
6 | let v = ARProjectedView()
7 | return v
8 | }
9 | override class func requiresMainQueueSetup() -> Bool {
10 | return false
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/ios/react_native-arkit-swift/ARSecondaryView.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import SceneKit
3 |
4 | @objc(ARSecondaryView)
5 | class ARSecondaryView: UIView {
6 | var sview: SCNView?
7 | var isStarted:Bool = false
8 |
9 | func start() -> ARSecondaryView {
10 | guard !isStarted else { return self }
11 | if Thread.isMainThread {
12 | guard let sm = ARSceneManager.sharedInstance else { return self }
13 | let v = SCNView()
14 | sview = v
15 | v.scene = sm.scene
16 | v.isPlaying = true
17 | v.autoenablesDefaultLighting = true
18 | sm.secondaryView = v
19 | addSubview(v)
20 | isStarted = true
21 | } else {
22 | DispatchQueue.main.async() {
23 | let _ = self.start()
24 | }
25 | }
26 | return self
27 | }
28 | override func layoutSubviews() {
29 | super.layoutSubviews()
30 | guard let v = sview else { return }
31 | v.frame = self.bounds
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/ios/react_native-arkit-swift/ARSecondaryViewManager.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | @objc(ARSecondaryViewManager)
3 | class ARSecondaryViewManager : RCTViewManager {
4 | override func view() -> ARSecondaryView {
5 | return (ARSecondaryView()).start()
6 | }
7 | override class func requiresMainQueueSetup() -> Bool {
8 | return false
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/ios/rn-swift-bridge.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import
4 | @interface RCT_EXTERN_MODULE(ARMonoViewManager, RCTViewManager)
5 | RCT_EXTERN_METHOD(doTap:(double)x y:(double)y resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
6 | RCT_EXPORT_VIEW_PROPERTY(preview, BOOL);
7 | RCT_EXPORT_VIEW_PROPERTY(debugMode, BOOL);
8 | @end
9 | @interface RCT_EXTERN_MODULE(ARPrimaryViewManager, RCTViewManager)
10 | RCT_EXPORT_VIEW_PROPERTY(interPupilaryDistance, float);
11 | RCT_EXPORT_VIEW_PROPERTY(holoOffsetY, float);
12 | RCT_EXPORT_VIEW_PROPERTY(holoOffsetZ, float);
13 | RCT_EXPORT_VIEW_PROPERTY(holoOffsetX, float);
14 | RCT_EXPORT_VIEW_PROPERTY(fieldOfView, float);
15 | @end
16 | @interface RCT_EXTERN_MODULE(ARProjectedViewManager, RCTViewManager)
17 | RCT_EXPORT_VIEW_PROPERTY(parentNode, NSString *);
18 | @end
19 | @interface RCT_EXTERN_MODULE(ARSceneManager, RCTEventEmitter)
20 | RCT_EXTERN_METHOD(addNode:(SCNNode *)node parentID:(NSString *)parentID resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
21 | RCT_EXTERN_METHOD(removeNode:(NSString *)id resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
22 | RCT_EXTERN_METHOD(updateNode:(NSString *)forNode newProps:(NSDictionary *)newProps resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
23 | RCT_EXTERN_METHOD(setBox:(SCNBox *)g forNode:(NSString *)forNode resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
24 | RCT_EXTERN_METHOD(setCapsule:(SCNCapsule *)g forNode:(NSString *)forNode resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
25 | RCT_EXTERN_METHOD(setCone:(SCNCone *)g forNode:(NSString *)forNode resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
26 | RCT_EXTERN_METHOD(setCylinder:(SCNCylinder *)g forNode:(NSString *)forNode resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
27 | RCT_EXTERN_METHOD(setPlane:(SCNPlane *)g forNode:(NSString *)forNode resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
28 | RCT_EXTERN_METHOD(setPyramid:(SCNPyramid *)g forNode:(NSString *)forNode resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
29 | RCT_EXTERN_METHOD(setSphere:(SCNSphere *)g forNode:(NSString *)forNode resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
30 | RCT_EXTERN_METHOD(setText:(SCNText *)g forNode:(NSString *)forNode resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
31 | RCT_EXTERN_METHOD(setTorus:(SCNTorus *)g forNode:(NSString *)forNode resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
32 | RCT_EXTERN_METHOD(setTube:(SCNTube *)g forNode:(NSString *)forNode resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
33 | RCT_EXTERN_METHOD(setShape:(SCNShape *)g forNode:(NSString *)forNode resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
34 | RCT_EXTERN_METHOD(setGeometry:(SCNGeometry *)geometry forNode:(NSString *)forNode resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
35 | RCT_EXTERN_METHOD(setLight:(SCNLight *)light forNode:(NSString *)forNode resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
36 | RCT_EXTERN_METHOD(removeLight:(NSString *)forNode resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
37 | RCT_EXTERN_METHOD(setMaterial:(SCNMaterial *)material forNode:(NSString *)forNode atPosition:(NSInteger)atPosition resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
38 | RCT_EXTERN_METHOD(setMaterialProperty:(NSDictionary *)json propertyName:(NSString *)propertyName forMaterialAtPosition:(NSInteger)forMaterialAtPosition forNode:(NSString *)forNode resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
39 | RCT_EXTERN_METHOD(removeGeometry:(NSString *)forNode resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
40 | RCT_EXTERN_METHOD(removeMaterial:(NSString *)forNode atPosition:(NSInteger)atPosition resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
41 | RCT_EXTERN_METHOD(setScene:(NSString *)forNode sourcePath:(NSString *)sourcePath resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
42 | RCT_EXTERN_METHOD(setModel:(NSString *)forNode sourcePath:(NSString *)sourcePath resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
43 | RCT_EXTERN_METHOD(addSKSceneReference:(SKScene *)scene resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
44 | RCT_EXTERN_METHOD(addSKSceneByReference:(NSString *)sceneName forNode:(NSString *)forNode atPosition:(NSInteger)atPosition withType:(NSString *)withType resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
45 | RCT_EXTERN_METHOD(addSKScene:(SKScene *)scene forNode:(NSString *)forNode atPosition:(NSInteger)atPosition withType:(NSString *)withType resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
46 | RCT_EXTERN_METHOD(updateSKScene:(NSDictionary *)scene forNode:(NSString *)forNode atPosition:(NSInteger)atPosition withType:(NSString *)withType resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
47 | RCT_EXTERN_METHOD(setSKLabelNode:(SKLabelNode *)node toParent:(NSString *)toParent resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
48 | RCT_EXTERN_METHOD(updateSKLabelNode:(NSDictionary *)json resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
49 | RCT_EXTERN_METHOD(setSKVideoNode:(SKVideoNode *)node toParent:(NSString *)toParent resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
50 | RCT_EXTERN_METHOD(updateSKVideoNode:(NSDictionary *)json resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
51 | RCT_EXTERN_METHOD(setSKNode:(SKNode *)node toParent:(NSString *)toParent resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
52 | RCT_EXTERN_METHOD(removeSKNode:(NSString *)name resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
53 | RCT_EXTERN_METHOD(removeSKScene:(NSString *)forNode atPosition:(NSInteger)atPosition withType:(NSString *)withType resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
54 | RCT_EXTERN_METHOD(addSKLabelNode:(SKLabelNode *)node toParent:(NSString *)toParent resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
55 | RCT_EXTERN_METHOD(addSKNode:(SKNode *)node toParent:(NSString *)toParent resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
56 | RCT_EXTERN_METHOD(clear:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
57 | RCT_EXTERN_METHOD(resume:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
58 | RCT_EXTERN_METHOD(pause:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
59 | RCT_EXTERN_METHOD(setAnimation:(double)seconds type:(NSString *)type resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
60 | RCT_EXTERN_METHOD(setAnimationDuration:(double)seconds resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
61 | RCT_EXTERN_METHOD(setAnimationType:(NSString *)type resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
62 | RCT_EXTERN_METHOD(setPlaneDetection:(NSString *)detectPlanes resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
63 | RCT_EXTERN_METHOD(getAnchors:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
64 | RCT_EXTERN_METHOD(removeAnchor:(NSString *)id resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
65 | RCT_EXTERN_METHOD(addRecognizerImage:(NSString *)url name:(NSString *)name width:(double)width resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
66 | RCT_EXTERN_METHOD(removeRecognizerImage:(NSString *)name resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
67 | RCT_EXTERN_METHOD(setImageDetection:(BOOL)doDetect resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
68 | RCT_EXTERN_METHOD(projectNode:(NSString *)nodeID resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
69 | RCT_EXTERN_METHOD(projectWorldPoint:(SCNVector3 *)v resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
70 | RCT_EXTERN_METHOD(setPOVSensitivity:(double)newSensitivity resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
71 | RCT_EXTERN_METHOD(setPOVOrientationSensitivity:(double)newSensitivity resolve:(RCTPromiseResolveBlock)resolve recject:(RCTPromiseRejectBlock)recject);
72 | RCT_EXTERN_METHOD(getPOV:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
73 | RCT_EXTERN_METHOD(setWorldTracking:(NSString *)trackingMode resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
74 | RCT_EXTERN_METHOD(hitTestPlane:(CGPoint *)point detectType:(NSString *)detectType resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
75 | @end
76 | @interface RCT_EXTERN_MODULE(ARSecondaryViewManager, RCTViewManager)
77 | @end
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-reality",
3 | "version": "1.1.0",
4 | "peerDependencies": {
5 | "react-native-pod": "^1.6.0",
6 | "react-native-swift": "^0.10.0"
7 | },
8 | "main": "index.js",
9 | "scripts": {
10 | "bridge": "react-native-swift-bridge",
11 | "watch": "react-native-swift-bridge --watch"
12 | },
13 | "dependencies": {
14 | "fast-deep-equal": "^1.0.0",
15 | "lodash": "^4.17.5",
16 | "prop-types": "^15.6.0",
17 | "react-adopt": "^0.6.0",
18 | "react-native-swift-bridge": "^2.4.2",
19 | "uuid": "^3.2.1"
20 | },
21 | "pods": {
22 | "PocketSVG": "*"
23 | },
24 | "devDependencies": {
25 | "react": "^16.3.0"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/yarn-error.log:
--------------------------------------------------------------------------------
1 | Arguments:
2 | /usr/local/Cellar/node/9.6.1/bin/node /usr/local/Cellar/yarn/1.5.1/libexec/bin/yarn.js watch
3 |
4 | PATH:
5 | /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/element55/published/tools/
6 |
7 | Yarn version:
8 | 1.5.1
9 |
10 | Node version:
11 | 9.6.1
12 |
13 | Platform:
14 | darwin x64
15 |
16 | npm manifest:
17 | {
18 | "name": "react-native-arkit-swift",
19 | "version": "0.0.1",
20 | "peerDependencies": {
21 | "react-native-pod": "^1.6.0",
22 | "react-native-swift": "^0.10.0"
23 | },
24 | "main": "index.js",
25 | "scripts": {
26 | "bridge": "react-native-swift-bridge",
27 | "watch": "react-native-swift-bridge --watch"
28 | },
29 | "dependencies": {
30 | "@panter/react-animation-frame": "^0.3.7",
31 | "fast-deep-equal": "^1.0.0",
32 | "lodash": "^4.17.5",
33 | "prop-types": "^15.6.0",
34 | "react-native-xcode": "^1.0.0",
35 | "uuid": "^3.2.1"
36 | },
37 | "pods": {
38 | "PocketSVG": "*"
39 | },
40 | "devDependencies": {
41 | "react": "^16.2.0"
42 | }
43 | }
44 |
45 | yarn manifest:
46 | No manifest
47 |
48 | Lockfile:
49 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
50 | # yarn lockfile v1
51 |
52 |
53 | "@panter/react-animation-frame@^0.3.7":
54 | version "0.3.7"
55 | resolved "https://registry.npmjs.org/@panter/react-animation-frame/-/react-animation-frame-0.3.7.tgz#31a0d7683e4a8d2e1b29ff512cad36513bd43d00"
56 | dependencies:
57 | react "15.4.2"
58 |
59 | asap@~2.0.3:
60 | version "2.0.6"
61 | resolved "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
62 |
63 | balanced-match@^1.0.0:
64 | version "1.0.0"
65 | resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
66 |
67 | brace-expansion@^1.1.7:
68 | version "1.1.8"
69 | resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
70 | dependencies:
71 | balanced-match "^1.0.0"
72 | concat-map "0.0.1"
73 |
74 | concat-map@0.0.1:
75 | version "0.0.1"
76 | resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
77 |
78 | core-js@^1.0.0:
79 | version "1.2.7"
80 | resolved "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
81 |
82 | encoding@^0.1.11:
83 | version "0.1.12"
84 | resolved "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
85 | dependencies:
86 | iconv-lite "~0.4.13"
87 |
88 | fast-deep-equal@^1.0.0:
89 | version "1.0.0"
90 | resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff"
91 |
92 | fbjs@^0.8.16, fbjs@^0.8.4:
93 | version "0.8.16"
94 | resolved "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
95 | dependencies:
96 | core-js "^1.0.0"
97 | isomorphic-fetch "^2.1.1"
98 | loose-envify "^1.0.0"
99 | object-assign "^4.1.0"
100 | promise "^7.1.1"
101 | setimmediate "^1.0.5"
102 | ua-parser-js "^0.7.9"
103 |
104 | fs.realpath@^1.0.0:
105 | version "1.0.0"
106 | resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
107 |
108 | glob@^7.1.2:
109 | version "7.1.2"
110 | resolved "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
111 | dependencies:
112 | fs.realpath "^1.0.0"
113 | inflight "^1.0.4"
114 | inherits "2"
115 | minimatch "^3.0.4"
116 | once "^1.3.0"
117 | path-is-absolute "^1.0.0"
118 |
119 | iconv-lite@~0.4.13:
120 | version "0.4.19"
121 | resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
122 |
123 | inflight@^1.0.4:
124 | version "1.0.6"
125 | resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
126 | dependencies:
127 | once "^1.3.0"
128 | wrappy "1"
129 |
130 | inherits@2:
131 | version "2.0.3"
132 | resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
133 |
134 | is-stream@^1.0.1:
135 | version "1.1.0"
136 | resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
137 |
138 | isomorphic-fetch@^2.1.1:
139 | version "2.2.1"
140 | resolved "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
141 | dependencies:
142 | node-fetch "^1.0.1"
143 | whatwg-fetch ">=0.10.0"
144 |
145 | js-tokens@^3.0.0:
146 | version "3.0.2"
147 | resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
148 |
149 | lodash@^4.17.5:
150 | version "4.17.5"
151 | resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511"
152 |
153 | loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
154 | version "1.3.1"
155 | resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
156 | dependencies:
157 | js-tokens "^3.0.0"
158 |
159 | minimatch@^3.0.4:
160 | version "3.0.4"
161 | resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
162 | dependencies:
163 | brace-expansion "^1.1.7"
164 |
165 | node-fetch@^1.0.1:
166 | version "1.7.3"
167 | resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
168 | dependencies:
169 | encoding "^0.1.11"
170 | is-stream "^1.0.1"
171 |
172 | object-assign@^4.1.0, object-assign@^4.1.1:
173 | version "4.1.1"
174 | resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
175 |
176 | once@^1.3.0:
177 | version "1.4.0"
178 | resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
179 | dependencies:
180 | wrappy "1"
181 |
182 | path-is-absolute@^1.0.0:
183 | version "1.0.1"
184 | resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
185 |
186 | promise@^7.1.1:
187 | version "7.3.1"
188 | resolved "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
189 | dependencies:
190 | asap "~2.0.3"
191 |
192 | prop-types@^15.6.0:
193 | version "15.6.0"
194 | resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
195 | dependencies:
196 | fbjs "^0.8.16"
197 | loose-envify "^1.3.1"
198 | object-assign "^4.1.1"
199 |
200 | react-native-xcode@^1.0.0:
201 | version "1.0.0"
202 | resolved "https://registry.npmjs.org/react-native-xcode/-/react-native-xcode-1.0.0.tgz#e6385a7e114cf7361fa855608d33c90a1d2c07c6"
203 | dependencies:
204 | glob "^7.1.2"
205 |
206 | react@15.4.2:
207 | version "15.4.2"
208 | resolved "https://registry.npmjs.org/react/-/react-15.4.2.tgz#41f7991b26185392ba9bae96c8889e7e018397ef"
209 | dependencies:
210 | fbjs "^0.8.4"
211 | loose-envify "^1.1.0"
212 | object-assign "^4.1.0"
213 |
214 | react@^16.2.0:
215 | version "16.2.0"
216 | resolved "https://registry.npmjs.org/react/-/react-16.2.0.tgz#a31bd2dab89bff65d42134fa187f24d054c273ba"
217 | dependencies:
218 | fbjs "^0.8.16"
219 | loose-envify "^1.1.0"
220 | object-assign "^4.1.1"
221 | prop-types "^15.6.0"
222 |
223 | setimmediate@^1.0.5:
224 | version "1.0.5"
225 | resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
226 |
227 | ua-parser-js@^0.7.9:
228 | version "0.7.17"
229 | resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"
230 |
231 | uuid@^3.2.1:
232 | version "3.2.1"
233 | resolved "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14"
234 |
235 | whatwg-fetch@>=0.10.0:
236 | version "2.0.3"
237 | resolved "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84"
238 |
239 | wrappy@1:
240 | version "1.0.2"
241 | resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
242 |
243 | Trace:
244 | Error: Command failed.
245 | Exit signal: SIGTERM
246 | Command: sh
247 | Arguments: -c react-native-swift-bridge --watch
248 | Directory: /Users/ray/Documents/react-native-arkit-swift
249 | Output:
250 |
251 | at ProcessTermError.MessageError (/usr/local/Cellar/yarn/1.5.1/libexec/lib/cli.js:186:110)
252 | at new ProcessTermError (/usr/local/Cellar/yarn/1.5.1/libexec/lib/cli.js:226:113)
253 | at ChildProcess. (/usr/local/Cellar/yarn/1.5.1/libexec/lib/cli.js:30281:17)
254 | at ChildProcess.emit (events.js:127:13)
255 | at maybeClose (internal/child_process.js:933:16)
256 | at Process.ChildProcess._handle.onexit (internal/child_process.js:220:5)
257 |
--------------------------------------------------------------------------------