Skip to content

Commit e75cd4c

Browse files
authored
Merge pull request #129 from HippoAR/error-handling-and-bugfixing
Error handling and bugfixing
2 parents 6b7d053 + 6fc30d9 commit e75cd4c

File tree

12 files changed

+134
-46
lines changed

12 files changed

+134
-46
lines changed

ARKit.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,10 @@ class ARKit extends Component {
7171
onTapOnPlaneUsingExtent={this.callback('onTapOnPlaneUsingExtent')}
7272
onTapOnPlaneNoExtent={this.callback('onTapOnPlaneNoExtent')}
7373
onPlaneDetected={this.callback('onPlaneDetected')}
74+
onPlaneRemoved={this.callback('onPlaneRemoved')}
7475
onPlaneUpdate={this.callback('onPlaneUpdate')}
7576
onTrackingState={this.callback('onTrackingState')}
77+
onARKitError={this.callback('onARKitError')}
7678
onEvent={this._onEvent}
7779
/>
7880
{state}
@@ -183,7 +185,9 @@ ARKit.propTypes = {
183185
lightEstimationEnabled: PropTypes.bool,
184186
autoenablesDefaultLighting: PropTypes.bool,
185187
worldAlignment: PropTypes.number,
188+
onARKitError: PropTypes.func,
186189
onPlaneDetected: PropTypes.func,
190+
onPlaneRemoved: PropTypes.func,
187191
onFeaturesDetected: PropTypes.func,
188192
// onLightEstimation is called rapidly, better poll with
189193
// ARKit.getCurrentLightEstimation()

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
3+
### 2017-12-21
4+
5+
- added `onPlaneRemoved`
6+
- added `eulerAngles` to detected planes
7+
- added `onARKitError` to ARKit
8+
- added `origin` property to ARKit

README.md

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ export default class ReactNativeARKit extends Component {
6969
onLightEstimation={e => console.log(e.nativeEvent)}
7070
onPlaneDetected={console.log} // event listener for plane detection
7171
onPlaneUpdate={console.log} // event listener for plane update
72+
onPlaneRemoved={console.log} // arkit sometimes removes detected planes
7273
>
7374
<ARKit.Box
7475
position={{ x: 0, y: 0, z: 0 }}
@@ -176,15 +177,31 @@ AppRegistry.registerComponent('ReactNativeARKit', () => ReactNativeARKit);
176177
| `planeDetection` | `Boolean` | `false` | ARKit plane detection.
177178
| `lightEstimationEnabled` | `Boolean` | `false` | ARKit light estimation.
178179
| `worldAlignment` | `Enumeration` <br /> One of: `ARKit.ARWorldAlignment.Gravity`, `ARKit.ARWorldAlignment.GravityAndHeading`, `ARKit.ARWorldAlignment.Camera` (documentation [here](https://developer.apple.com/documentation/arkit/arworldalignment)) | `ARKit.ARWorldAlignment.Gravity` | **ARWorldAlignmentGravity** <br /> The coordinate system's y-axis is parallel to gravity, and its origin is the initial position of the device. **ARWorldAlignmentGravityAndHeading** <br /> The coordinate system's y-axis is parallel to gravity, its x- and z-axes are oriented to compass heading, and its origin is the initial position of the device. **ARWorldAlignmentCamera** <br /> The scene coordinate system is locked to match the orientation of the camera.|
180+
| `origin` | `{position, transition}` | Usually `{0,0,0}` is where you launched the app. If you want to have a different origin, you can set it here. E.g. if you set `origin={{position: {0,-1, 0}, transition: {duration: 1}}}` the new origin will be one meter below. If you have any objects already placed, they will get moved down using the given transition. All hit-test functions or similar will report coordinates relative to that new origin as `position`. You can get the original coordinates with `positionAbsolute` in these functions |
179181

180182
##### Events
181183

182184
| Event Name | Returns | Notes
183185
|---|---|---|
184-
| `onPlaneDetected` | `{ id, center, extent }` | When a plane is first detected.
186+
| `onARKitError` | `ARKiterror` | will report whether an error occured while initializing ARKit. A common error is when the user has not allowed camera access. Another error is, if you use `worldAlignment=GravityAndHeading` and location service is turned off |
185187
| `onLightEstimation` | `{ ambientColorTemperature, ambientIntensity }` | Light estimation on every frame. Called rapidly, better use polling. See `ARKit.getCurrentLightEstimation()`
186188
| `onFeaturesDetected` | `{ featurePoints}` | Detected Features on every frame (currently also not throttled). Usefull to display custom dots for detected features. You can also poll this information with `ARKit.getCurrentDetectedFeaturePoints()`
187-
| `onPlaneUpdate` | `{ id, center, extent }` | When a detected plane is updated
189+
| `onPlaneDetected` | `Plane` | When a plane is first detected.
190+
| `onPlaneUpdate` | `Plane` | When a detected plane is updated
191+
| `onPlaneRemoved` | `Plane` | When a detected plane is updated
192+
193+
The `Plane` object has the following properties:
194+
195+
| Property | Description
196+
|---|---|
197+
| `id` | a unique id identifying the plane |
198+
| `position` | the position of the plane (relative to the origin) |
199+
| `positionAbsolute` | the absolute position of the plane |
200+
| `extent` | the extent of the plane |
201+
| `eulerAngles` | the rotation of the plane |
202+
203+
204+
188205

189206
##### Static methods
190207

@@ -253,7 +270,7 @@ Most objects take a material property with these sub-props:
253270
| `doubleSided` | boolean | render both sides, default is `true` |
254271
| `litPerPixel` | boolean | calculate lighting per-pixel or vertex [litPerPixel](https://developer.apple.com/documentation/scenekit/scnmaterial/1462580-litperpixel) |
255272
| `lightingModel` | `ARKit.LightingModel.*` | [LightingModel](https://developer.apple.com/documentation/scenekit/scnmaterial.lightingmodel) |
256-
| `blendMode` | `ARKit.BlendMode.*` | [BlendMode](https://developer.apple.com/documentation/scenekit/scnmaterial/1462585-blendmode) |
273+
| `blendMode` | `ARKit.BlendMode.*` | [BlendMode](https://developer.apple.com/documentation/scenekit/scnmaterial/1462585-blendmode) |
257274
| `fillMode` | `ARKit.FillMode.*` | [FillMode](https://developer.apple.com/documentation/scenekit/scnmaterial/2867442-fillmode)
258275
| `shaders` | Object with keys from `ARKit.ShaderModifierEntryPoint.*` and shader strings as values | [Shader modifiers](https://developer.apple.com/documentation/scenekit/scnshadable) |
259276
| `colorBufferWriteMask` | `ARKit.ColorMask.*` | [color mask](https://developer.apple.com/documentation/scenekit/scncolormask). Set to ARKit.ColorMask.None so that an object is transparent, but receives deferred shadows. |

components/lib/createArComponent.js

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ export default (mountConfig, propTypes = {}, nonUpdateablePropKeys = []) => {
8888
: mountConfig.mount;
8989

9090
const mount = (id, props) => {
91+
if (DEBUG) console.log(`[${id}] [${new Date().getTime()}] mount`, props);
9192
mountFunc(
9293
getNonNodeProps(props),
9394
{
@@ -98,6 +99,16 @@ export default (mountConfig, propTypes = {}, nonUpdateablePropKeys = []) => {
9899
);
99100
};
100101

102+
const update = (id, props) => {
103+
if (DEBUG) console.log(`[${id}] [${new Date().getTime()}] update`, props);
104+
ARGeosManager.updateNode(id, props);
105+
};
106+
107+
const unmount = id => {
108+
if (DEBUG) console.log(`[${id}] [${new Date().getTime()}] unmount`);
109+
ARGeosManager.unmount(id);
110+
};
111+
101112
const ARComponent = class extends Component {
102113
identifier = null;
103114
componentDidMount() {
@@ -108,7 +119,7 @@ export default (mountConfig, propTypes = {}, nonUpdateablePropKeys = []) => {
108119
const {
109120
transition: transitionOnMount = { duration: 0 },
110121
} = fullPropsOnMount;
111-
if (DEBUG) console.log('mount', fullPropsOnMount);
122+
112123
this.doPendingTimers();
113124
mount(this.identifier, fullPropsOnMount);
114125

@@ -137,13 +148,20 @@ export default (mountConfig, propTypes = {}, nonUpdateablePropKeys = []) => {
137148
);
138149
if (nonAllowedUpdates.length > 0) {
139150
throw new Error(
140-
`prop can't be updated: '${nonAllowedUpdates.join(', ')}'`,
151+
`[${this
152+
.identifier}] prop can't be updated: '${nonAllowedUpdates.join(
153+
', ',
154+
)}'`,
141155
);
142156
}
143157
}
144158

145159
if (some(changedKeys, k => nonUpdateablePropKeys.includes(k))) {
146-
if (DEBUG) console.log('need to remount node because of ', changedKeys);
160+
if (DEBUG)
161+
console.log(
162+
`[${this.identifier}] need to remount node because of `,
163+
changedKeys,
164+
);
147165
mount(this.identifier, { ...this.props, ...props });
148166
} else {
149167
// every property is updateable
@@ -158,8 +176,7 @@ export default (mountConfig, propTypes = {}, nonUpdateablePropKeys = []) => {
158176
...parseMaterials(pick(props, changedKeys)),
159177
};
160178

161-
if (DEBUG) console.log('update node', propsToupdate);
162-
ARGeosManager.updateNode(this.identifier, propsToupdate);
179+
update(this.identifier, propsToupdate);
163180
}
164181
}
165182

@@ -171,11 +188,11 @@ export default (mountConfig, propTypes = {}, nonUpdateablePropKeys = []) => {
171188

172189
this.componentWillUpdate(fullProps);
173190
this.delayed(() => {
174-
ARGeosManager.unmount(this.identifier);
191+
unmount(this.identifier);
175192
}, duration * 1000);
176193
} else {
177194
this.doPendingTimers();
178-
ARGeosManager.unmount(this.identifier);
195+
unmount(this.identifier);
179196
}
180197
}
181198
/**

ios/RCTARKit.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,15 @@ typedef void (^RCTARKitReject)(NSString *code, NSString *message, NSError *error
4141
@property (nonatomic, assign) ARWorldAlignment worldAlignment;
4242

4343
@property (nonatomic, copy) RCTBubblingEventBlock onPlaneDetected;
44+
@property (nonatomic, copy) RCTBubblingEventBlock onPlaneRemoved;
4445
@property (nonatomic, copy) RCTBubblingEventBlock onFeaturesDetected;
4546
@property (nonatomic, copy) RCTBubblingEventBlock onLightEstimation;
4647
@property (nonatomic, copy) RCTBubblingEventBlock onPlaneUpdate;
4748
@property (nonatomic, copy) RCTBubblingEventBlock onTrackingState;
4849
@property (nonatomic, copy) RCTBubblingEventBlock onTapOnPlaneUsingExtent;
4950
@property (nonatomic, copy) RCTBubblingEventBlock onTapOnPlaneNoExtent;
5051
@property (nonatomic, copy) RCTBubblingEventBlock onEvent;
52+
@property (nonatomic, copy) RCTBubblingEventBlock onARKitError;
5153

5254

5355
@property NSMutableDictionary *planes; // plane detected

ios/RCTARKit.m

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ - (instancetype)initWithARView:(ARSCNView *)arView {
8787

8888
- (void)layoutSubviews {
8989
[super layoutSubviews];
90+
//NSLog(@"setting view bounds %@", NSStringFromCGRect(self.bounds));
9091
self.arView.frame = self.bounds;
9192
}
9293

@@ -98,6 +99,15 @@ - (void)resume {
9899
[self.session runWithConfiguration:self.configuration];
99100
}
100101

102+
- (void)session:(ARSession *)session didFailWithError:(NSError *)error {
103+
if(self.onARKitError) {
104+
self.onARKitError(RCTJSErrorFromNSError(error));
105+
} else {
106+
NSLog(@"Initializing ARKIT failed with Error: %@ %@", error, [error userInfo]);
107+
108+
}
109+
110+
}
101111
- (void)reset {
102112
if (ARWorldTrackingConfiguration.isSupported) {
103113
[self.session runWithConfiguration:self.configuration options:ARSessionRunOptionRemoveExistingAnchors | ARSessionRunOptionResetTracking];
@@ -471,12 +481,13 @@ - (NSDictionary *)makePlaneDetectionResult:(SCNNode *)node planeAnchor:(ARPlaneA
471481
return @{
472482
@"id": planeAnchor.identifier.UUIDString,
473483
@"alignment": @(planeAnchor.alignment),
484+
@"eulerAngles":vectorToJson(node.eulerAngles),
474485
@"position": vectorToJson([self.nodeManager getRelativePositionToOrigin:node.position]),
475486
@"positionAbsolute": vectorToJson(node.position),
476-
// node is deprecated
477-
@"node": vectorToJson(node.position),
478487
@"center": vector_float3ToJson(planeAnchor.center),
479-
@"extent": vector_float3ToJson(planeAnchor.extent)
488+
@"extent": vector_float3ToJson(planeAnchor.extent),
489+
// node is deprecated
490+
@"node": vectorToJson(node.position)
480491
};
481492
}
482493

@@ -505,6 +516,13 @@ - (void)renderer:(id <SCNSceneRenderer>)renderer didUpdateNode:(SCNNode *)node f
505516

506517
}
507518

519+
- (void)renderer:(id<SCNSceneRenderer>)renderer didRemoveNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor {
520+
ARPlaneAnchor *planeAnchor = (ARPlaneAnchor *)anchor;
521+
if (self.onPlaneRemoved) {
522+
self.onPlaneRemoved([self makePlaneDetectionResult:node planeAnchor:planeAnchor]);
523+
}
524+
}
525+
508526

509527

510528

ios/RCTARKitManager.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ @implementation RCTARKitManager
1717

1818
RCT_EXPORT_MODULE()
1919

20+
21+
2022
- (UIView *)view {
2123
return [ARKit sharedInstance];
2224
}
@@ -102,12 +104,14 @@ - (NSDictionary *)constantsToExport
102104

103105
RCT_EXPORT_VIEW_PROPERTY(onPlaneDetected, RCTBubblingEventBlock)
104106
RCT_EXPORT_VIEW_PROPERTY(onPlaneUpdate, RCTBubblingEventBlock)
107+
RCT_EXPORT_VIEW_PROPERTY(onPlaneRemoved, RCTBubblingEventBlock)
105108
RCT_EXPORT_VIEW_PROPERTY(onTrackingState, RCTBubblingEventBlock)
106109
RCT_EXPORT_VIEW_PROPERTY(onFeaturesDetected, RCTBubblingEventBlock)
107110
RCT_EXPORT_VIEW_PROPERTY(onLightEstimation, RCTBubblingEventBlock)
108111
RCT_EXPORT_VIEW_PROPERTY(onTapOnPlaneUsingExtent, RCTBubblingEventBlock)
109112
RCT_EXPORT_VIEW_PROPERTY(onTapOnPlaneNoExtent, RCTBubblingEventBlock)
110113
RCT_EXPORT_VIEW_PROPERTY(onEvent, RCTBubblingEventBlock)
114+
RCT_EXPORT_VIEW_PROPERTY(onARKitError, RCTBubblingEventBlock)
111115

112116
RCT_EXPORT_METHOD(pause:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
113117
[[ARKit sharedInstance] pause];

ios/RCTARKitNodes.m

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ - (instancetype)init {
6161
}
6262

6363
- (void)setArView:(ARSCNView *)arView {
64-
NSLog(@"setArView");
64+
//NSLog(@"setArView");
6565
_arView = arView;
6666
self.rootNode = arView.scene.rootNode;
6767

@@ -78,6 +78,7 @@ - (void)setArView:(ARSCNView *)arView {
7878
add a node to scene in a reference frame
7979
*/
8080
- (void)addNodeToScene:(SCNNode *)node inReferenceFrame:(NSString *)referenceFrame {
81+
[self registerNode:node forKey:node.name];
8182
if (!referenceFrame) {
8283
referenceFrame = @"Local"; // default to Local frame
8384
}
@@ -108,24 +109,23 @@ - (void)clear {
108109
- (void)addNodeToLocalFrame:(SCNNode *)node {
109110
node.referenceFrame = RFReferenceFrameLocal;
110111

112+
[self.localOrigin addChildNode:node];
111113
//NSLog(@"[RCTARKitNodes] Add node %@ to Local frame at (%.2f, %.2f, %.2f)", node.name, node.position.x, node.position.y, node.position.z);
112114

113-
[self registerNode:node forKey:node.name];
114-
[self.localOrigin addChildNode:node];
115115
}
116116

117117
- (void)addNodeToCameraFrame:(SCNNode *)node {
118118
node.referenceFrame = RFReferenceFrameCamera;
119119
//NSLog(@"[RCTARKitNodes] Add node %@ to Camera frame at (%.2f, %.2f, %.2f)", node.name, node.position.x, node.position.y, node.position.z);
120-
[self registerNode:node forKey:node.name];
120+
121121
[self.cameraOrigin addChildNode:node];
122122
}
123123

124124
- (void)addNodeToFrontOfCameraFrame:(SCNNode *)node {
125125
node.referenceFrame = RFReferenceFrameFrontOfCamera;
126126

127127
//NSLog(@"[RCTARKitNodes] Add node %@ to FrontOfCamera frame at (%.2f, %.2f, %.2f)", node.name, node.position.x, node.position.y, node.position.z);
128-
[self registerNode:node forKey:node.name];
128+
129129
[self.frontOfCamera addChildNode:node];
130130
}
131131

@@ -287,7 +287,7 @@ - (SCNNode *)nodeForKey:(NSString *)key {
287287
}
288288

289289
- (void)removeNodeForKey:(NSString *)key {
290-
290+
//NSLog(@"removing node: %@ ", key);
291291
SCNNode *node = [self.nodes objectForKey:key];
292292
if (node) {
293293
[self.nodes removeObjectForKey:key];
@@ -303,6 +303,7 @@ - (void)removeNodeForKey:(NSString *)key {
303303

304304
- (void)updateNode:(NSString *)nodeId properties:(NSDictionary *) properties {
305305
SCNNode *node = [self.nodes objectForKey:nodeId];
306+
//NSLog(@"updating node %@ :%@", nodeId, properties);
306307
if(node) {
307308
[RCTConvert setNodeProperties:node properties:properties];
308309
if(node.geometry && properties[@"shape"]) {
@@ -318,6 +319,8 @@ - (void)updateNode:(NSString *)nodeId properties:(NSDictionary *) properties {
318319
}
319320

320321

322+
} else {
323+
NSLog(@"WARNING: node does not exists: %@. This means that the node has not been mounted yet, so native calls got out of order", nodeId);
321324
}
322325

323326
}

ios/RCTConvert+ARKit.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ + (void)setNodeProperties:(SCNNode *)node properties:(id)json {
413413
}
414414

415415
if (json[@"scale"]) {
416+
416417
CGFloat scale = [json[@"scale"] floatValue];
417418
node.scale = SCNVector3Make(scale, scale, scale);
418419

ios/color-grabber/color-grabber.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ - (NSArray *)getColorsFromImage:(UIImage *)image options:(NSDictionary *)options
9595
int red = CLAMP([reds[r] intValue], 0, 255);
9696
int green = CLAMP([greens[g] intValue], 0, 255);
9797
int blue = CLAMP([blues[b] intValue], 0, 255);
98-
NSLog([NSString stringWithFormat:@"r: %d, g: %d, b: %d",red,green,blue]);
98+
//NSLog([NSString stringWithFormat:@"r: %d, g: %d, b: %d",red,green,blue]);
9999

100100
NSString * rgbString = [NSString stringWithFormat:@"%i,%i,%i",red,green,blue];
101101
[flexibleColours addObject:rgbString];
@@ -167,7 +167,7 @@ - (NSArray *)getColorsFromImage:(UIImage *)image options:(NSDictionary *)options
167167
for (NSString * key in temp){
168168
float count = [temp[key] floatValue];
169169
float percentage = count/totalCount;
170-
NSLog(@"%f",percentage);
170+
//NSLog(@"%f",percentage);
171171
NSArray * rgb = [key componentsSeparatedByString:@","];
172172
float r = [rgb[0] floatValue];
173173
float g = [rgb[1] floatValue];

0 commit comments

Comments
 (0)