diff --git a/ARKit.js b/ARKit.js
index 6d85c689..3981e347 100644
--- a/ARKit.js
+++ b/ARKit.js
@@ -13,7 +13,7 @@ import {
View,
Text,
NativeModules,
- requireNativeComponent,
+ requireNativeComponent
} from 'react-native';
import generateId from './components/lib/generateId';
@@ -26,7 +26,7 @@ const TRACKING_REASONS = [
'NONE',
'INITIALIZING',
'EXCESSIVE_MOTION',
- 'INSUFFICIENT_FEATURES',
+ 'INSUFFICIENT_FEATURES'
];
const TRACKING_STATES_COLOR = ['red', 'orange', 'green'];
@@ -34,7 +34,7 @@ class ARKit extends Component {
state = {
state: 0,
reason: 0,
- floor: null,
+ floor: null
};
componentWillMount() {
ARKitManager.clearScene();
@@ -55,7 +55,7 @@ class ARKit extends Component {
@@ -84,13 +84,13 @@ class ARKit extends Component {
_onTrackingState = ({
state = this.state.state,
reason = this.state.reason,
- floor,
+ floor
}) => {
if (this.props.onTrackingState) {
this.props.onTrackingState({
state: TRACKING_STATES[state] || state,
reason: TRACKING_REASONS[reason] || reason,
- floor,
+ floor
});
}
@@ -98,7 +98,7 @@ class ARKit extends Component {
this.setState({
state,
reason,
- floor: floor ? floor.toFixed(2) : this.state.floor,
+ floor: floor ? floor.toFixed(2) : this.state.floor
});
}
};
@@ -138,19 +138,19 @@ const styles = StyleSheet.create({
borderRadius: 10,
padding: 4,
backgroundColor: 'black',
- flexDirection: 'row',
+ flexDirection: 'row'
},
stateIcon: {
width: 12,
height: 12,
borderRadius: 6,
- marginRight: 4,
+ marginRight: 4
},
stateText: {
color: 'white',
fontSize: 10,
- height: 12,
- },
+ height: 12
+ }
});
// copy all ARKitManager properties to ARKit
@@ -160,7 +160,7 @@ Object.keys(ARKitManager).forEach(key => {
const addDefaultsToSnapShotFunc = funcName => ({
target = 'cameraRoll',
- format = 'png',
+ format = 'png'
}) => ARKitManager[funcName]({ target, format });
ARKit.snapshot = addDefaultsToSnapShotFunc('snapshot');
@@ -182,7 +182,7 @@ ARKit.propTypes = {
onTrackingState: PropTypes.func,
onTapOnPlaneUsingExtent: PropTypes.func,
onTapOnPlaneNoExtent: PropTypes.func,
- onEvent: PropTypes.func,
+ onEvent: PropTypes.func
};
const RCTARKit = requireNativeComponent('RCTARKit', ARKit);
diff --git a/README.md b/README.md
index 726bfaa1..ed1866f1 100644
--- a/README.md
+++ b/README.md
@@ -23,15 +23,18 @@ There is a Slack group that anyone can join for help / support / general questio
`$ react-native link react-native-arkit`
+! Currently automatic installation does not work as PocketSVG is missing. Follow the manual installation
+
### Manual installation
#### iOS
1. In XCode, in the project navigator, right click `Libraries` ➜ `Add Files to [your project's name]`
-2. Go to `node_modules` ➜ `react-native-arkit` and add `RCTARKit.xcodeproj`
-3. In XCode, in the project navigator, select your project. Add `libRCTARKit.a` to your project's `Build Phases` ➜ `Link Binary With Libraries`
-4. Run your project (`Cmd+R`)<
+2. Go to `node_modules` ➜ add `react-native-arkit/RCTARKit.xcodeproj` and `_PocketSVG/_PocketSVG.xcodeproj`
+3. In XCode, in the project navigator, select your project. Add `libRCTARKit.a` `and PocketSVG.framework` to your project's `Build Phases` ➜ `Link Binary With Libraries`
+4. In Tab `General` ➜ `Embedded Binaries` ➜ `+` ➜ Add `PocketSVG.framework ios`
+5. Run your project (`Cmd+R`)<
## Usage
@@ -100,11 +103,32 @@ export default class ReactNativeARKit extends Component {
/>
+
+
+ `,
+ pathFlatness: 0.1,
+ // it's also possible to specify a chamfer profile:
+ chamferRadius: 5,
+ chamferProfilePathSvg: `
+
+ `,
+ extrusion: 10,
+ }}
+ />
);
@@ -273,6 +297,20 @@ SceneKit only supports `.scn` and `.dae` formats.
| `eulerAngles` | `{ x, y, z }` |
| `model` | `{ file, node, scale, alpha }` |
+#### ``
+
+Creates a extruded shape by an svg path.
+See https://github.com/HippoAR/react-native-arkit/pull/89 for details
+
+##### Props
+
+| Prop | Type |
+|---|---|
+| `position` | `{ x, y, z }` |
+| `eulerAngles` | `{ x, y, z }` |
+| `shape` | `{ pathSvg, extrusion, pathFlatness, chamferRadius, chamferProfilePathSvg, chamferProfilePathFlatness }` |
+
+
## Contributing
diff --git a/components/ARShape.js b/components/ARShape.js
new file mode 100644
index 00000000..4cf6cfd7
--- /dev/null
+++ b/components/ARShape.js
@@ -0,0 +1,18 @@
+import PropTypes from 'prop-types';
+
+import { chamferMode } from './lib/propTypes';
+import createArComponent from './lib/createArComponent';
+
+const ARShape = createArComponent('addShape', {
+ shape: PropTypes.shape({
+ extrusion: PropTypes.number,
+ pathSvg: PropTypes.string,
+ pathFlatness: PropTypes.number,
+ chamferMode,
+ chamferRadius: PropTypes.number,
+ chamferProfilePathSvg: PropTypes.string,
+ chamferProfilePathFlatness: PropTypes.string
+ })
+});
+
+module.exports = ARShape;
diff --git a/components/ARSprite.js b/components/ARSprite.js
index f44022af..0052f365 100644
--- a/components/ARSprite.js
+++ b/components/ARSprite.js
@@ -1,5 +1,5 @@
import React, { Component } from 'react';
-import withAnimationFrame from 'react-animation-frame';
+import withAnimationFrame from '@panter/react-animation-frame';
import { NativeModules, Animated } from 'react-native';
@@ -13,7 +13,7 @@ const ARSprite = withAnimationFrame(
super(props);
this.state = {
zIndex: new Animated.Value(),
- pos2D: new Animated.ValueXY(), // inits to zero
+ pos2D: new Animated.ValueXY() // inits to zero
};
}
onAnimationFrame() {
@@ -22,9 +22,9 @@ const ARSprite = withAnimationFrame(
{
x: this.state.pos2D.x,
y: this.state.pos2D.y,
- z: this.state.zIndex,
- },
- ]),
+ z: this.state.zIndex
+ }
+ ])
);
}
@@ -34,18 +34,18 @@ const ARSprite = withAnimationFrame(
style={{
position: 'absolute',
transform: this.state.pos2D.getTranslateTransform(),
- ...this.props.style,
+ ...this.props.style
}}
>
{this.props.children}
);
}
- },
+ }
);
ARSprite.propTypes = {
- position,
+ position
};
module.exports = ARSprite;
diff --git a/components/lib/createArComponent.js b/components/lib/createArComponent.js
index f48ecd78..df09ebe1 100644
--- a/components/lib/createArComponent.js
+++ b/components/lib/createArComponent.js
@@ -15,7 +15,7 @@ import {
orientation,
position,
rotation,
- transition,
+ transition
} from './propTypes';
import { processColorInMaterial } from './parseColor';
import generateId from './generateId';
@@ -25,14 +25,15 @@ const NODE_PROPS = [
'position',
'eulerAngles',
'rotation',
+ 'scale',
'orientation',
- 'transition',
+ 'transition'
];
const KEYS_THAT_NEED_REMOUNT = ['material', 'shape', 'model'];
const nodeProps = (id, props) => ({
id,
- ...pick(props, NODE_PROPS),
+ ...pick(props, NODE_PROPS)
});
export default (mountConfig, propTypes = {}) => {
@@ -40,11 +41,11 @@ export default (mountConfig, propTypes = {}) => {
typeof mountConfig === 'string'
? {
shape: props.shape,
- material: processColorInMaterial(props.material),
+ material: processColorInMaterial(props.material)
}
: {
...pick(props, mountConfig.pick),
- material: processColorInMaterial(props.material),
+ material: processColorInMaterial(props.material)
};
const mountFunc =
@@ -56,7 +57,7 @@ export default (mountConfig, propTypes = {}) => {
mountFunc(
getShapeAndMaterialProps(props),
nodeProps(id, props),
- props.frame,
+ props.frame
);
};
@@ -71,7 +72,7 @@ export default (mountConfig, propTypes = {}) => {
componentWillUpdate(props) {
const changedKeys = filter(
keys(this.props),
- key => !isDeepEqual(props[key], this.props[key]),
+ key => !isDeepEqual(props[key], this.props[key])
);
if (isEmpty(changedKeys)) {
@@ -87,7 +88,7 @@ export default (mountConfig, propTypes = {}) => {
// always include transition
ARGeosManager.update(
this.identifier,
- pick(props, ['transition', ...changedKeys]),
+ pick(props, ['transition', ...changedKeys])
);
}
}
@@ -108,7 +109,7 @@ export default (mountConfig, propTypes = {}) => {
rotation,
orientation,
material,
- ...propTypes,
+ ...propTypes
};
return ARComponent;
diff --git a/components/lib/propTypes.js b/components/lib/propTypes.js
index 97a48d45..db9d52f8 100644
--- a/components/lib/propTypes.js
+++ b/components/lib/propTypes.js
@@ -8,43 +8,44 @@ const ARKitManager = NativeModules.ARKitManager;
export const position = PropTypes.shape({
x: PropTypes.number,
y: PropTypes.number,
- z: PropTypes.number,
+ z: PropTypes.number
});
export const transition = PropTypes.shape({
- duration: PropTypes.number,
+ duration: PropTypes.number
});
export const eulerAngles = PropTypes.shape({
x: PropTypes.number,
y: PropTypes.number,
- z: PropTypes.number,
+ z: PropTypes.number
});
export const rotation = PropTypes.shape({
x: PropTypes.number,
y: PropTypes.number,
z: PropTypes.number,
- w: PropTypes.number,
+ w: PropTypes.number
});
export const orientation = PropTypes.shape({
x: PropTypes.number,
y: PropTypes.number,
z: PropTypes.number,
- w: PropTypes.number,
+ w: PropTypes.number
});
export const shaders = PropTypes.shape({
[ARKitManager.ShaderModifierEntryPoint.Geometry]: PropTypes.string,
[ARKitManager.ShaderModifierEntryPoint.Surface]: PropTypes.string,
[ARKitManager.ShaderModifierEntryPoint.LightingModel]: PropTypes.string,
- [ARKitManager.ShaderModifierEntryPoint.Fragment]: PropTypes.string,
+ [ARKitManager.ShaderModifierEntryPoint.Fragment]: PropTypes.string
});
export const lightingModel = PropTypes.oneOf(
- values(ARKitManager.LightingModel),
+ values(ARKitManager.LightingModel)
);
export const blendMode = PropTypes.oneOf(values(ARKitManager.BlendMode));
+export const chamferMode = PropTypes.oneOf(values(ARKitManager.ChamferMode));
export const material = PropTypes.shape({
color: PropTypes.string,
@@ -52,5 +53,5 @@ export const material = PropTypes.shape({
roughness: PropTypes.number,
blendMode,
lightingModel,
- shaders,
+ shaders
});
diff --git a/index.js b/index.js
index d54139eb..e832bb32 100644
--- a/index.js
+++ b/index.js
@@ -21,6 +21,7 @@ import ARText from './components/ARText';
import ARModel from './components/ARModel';
import ARSprite from './components/ARSprite';
import ARGroup from './components/ARGroup';
+import ARShape from './components/ARShape';
ARKit.Box = ARBox;
ARKit.Sphere = ARSphere;
@@ -35,6 +36,7 @@ ARKit.Text = ARText;
ARKit.Model = ARModel;
ARKit.Sprite = ARSprite;
ARKit.Group = ARGroup;
+ARKit.Shape = ARShape;
module.exports = {
ARKit,
@@ -50,5 +52,5 @@ module.exports = {
ARPlane,
ARText,
ARModel,
- ARGroup,
+ ARGroup
};
diff --git a/ios/RCTARKit.m b/ios/RCTARKit.m
index 8d6b2b60..9abc35bf 100644
--- a/ios/RCTARKit.m
+++ b/ios/RCTARKit.m
@@ -435,26 +435,28 @@ - (void)session:(ARSession *)session didUpdateFrame:(ARFrame *)frame {
}
}
if (self.onFeaturesDetected) {
+ NSMutableArray * featurePoints = [NSMutableArray array];
+ for (int i = 0; i < frame.rawFeaturePoints.count; i++) {
+ vector_float3 point = frame.rawFeaturePoints.points[i];
+
+ NSString * pointId = [NSString stringWithFormat:@"featurepoint_%lld",frame.rawFeaturePoints.identifiers[i]];
+
+ [featurePoints addObject:@{
+ @"x": @(point[0]),
+ @"y": @(point[1]),
+ @"z": @(point[2]),
+ @"id":pointId,
+ }];
+
+ }
dispatch_async(dispatch_get_main_queue(), ^{
- NSMutableArray * featurePoints = [NSMutableArray array];
- for (int i = 0; i < frame.rawFeaturePoints.count; i++) {
- vector_float3 point = frame.rawFeaturePoints.points[i];
-
- NSString * pointId = [NSString stringWithFormat:@"featurepoint_%lld",frame.rawFeaturePoints.identifiers[i]];
-
- [featurePoints addObject:@{
- @"x": @(point[0]),
- @"y": @(point[1]),
- @"z": @(point[2]),
- @"id":pointId,
- }];
-
- }
- self.onFeaturesDetected(@{
- @"featurePoints":featurePoints
- });
+ if(self.onFeaturesDetected) {
+ self.onFeaturesDetected(@{
+ @"featurePoints":featurePoints
+ });
+ }
});
}
}
diff --git a/ios/RCTARKit.xcodeproj/project.pbxproj b/ios/RCTARKit.xcodeproj/project.pbxproj
index aa4ab109..b180ffd6 100644
--- a/ios/RCTARKit.xcodeproj/project.pbxproj
+++ b/ios/RCTARKit.xcodeproj/project.pbxproj
@@ -29,6 +29,15 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ B14C363A1F9504D70047CB67 /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
@@ -52,6 +61,8 @@
10FEF6121F774C9000EC21AE /* RCTARKitNodes.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTARKitNodes.m; sourceTree = ""; };
10FEF6131F774C9000EC21AE /* RCTARKitDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTARKitDelegate.h; sourceTree = ""; };
134814201AA4EA6300B7C361 /* libRCTARKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTARKit.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ B14C36631F960C500047CB67 /* PocketSVG.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = PocketSVG.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ B14C36651F960C6E0047CB67 /* PocketSVG.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = PocketSVG.framework; sourceTree = BUILT_PRODUCTS_DIR; };
B3E7B5881CC2AC0600A0062D /* RCTARKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTARKit.h; sourceTree = ""; };
B3E7B5891CC2AC0600A0062D /* RCTARKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTARKit.m; sourceTree = ""; };
/* End PBXFileReference section */
@@ -108,7 +119,17 @@
105F124C1F7C0718006D4BA3 /* RCTConvert+ARKit.h */,
105F124D1F7C0718006D4BA3 /* RCTConvert+ARKit.m */,
134814211AA4EA7D00B7C361 /* Products */,
+ B13FF7601F94F72400A6C92B /* Frameworks */,
+ );
+ sourceTree = "";
+ };
+ B13FF7601F94F72400A6C92B /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ B14C36651F960C6E0047CB67 /* PocketSVG.framework */,
+ B14C36631F960C500047CB67 /* PocketSVG.framework */,
);
+ name = Frameworks;
sourceTree = "";
};
/* End PBXGroup section */
@@ -121,6 +142,7 @@
58B511D71A9E6C8500147676 /* Sources */,
58B511D81A9E6C8500147676 /* Frameworks */,
58B511D91A9E6C8500147676 /* CopyFiles */,
+ B14C363A1F9504D70047CB67 /* CopyFiles */,
);
buildRules = (
);
@@ -269,6 +291,7 @@
"$(SRCROOT)/../../react-native-arcl/ios",
../../../ios/Pods/Headers/Public/,
../../../ios/Pods/Headers/Public/React,
+ "$(SRCROOT)/../../_PocketSVG/**",
);
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LIBRARY_SEARCH_PATHS = "$(inherited)";
@@ -290,6 +313,7 @@
"$(SRCROOT)/../../react-native-arcl/ios",
../../../ios/Pods/Headers/Public/,
../../../ios/Pods/Headers/Public/React,
+ "$(SRCROOT)/../../_PocketSVG/**",
);
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LIBRARY_SEARCH_PATHS = "$(inherited)";
diff --git a/ios/RCTARKitManager.m b/ios/RCTARKitManager.m
index 5c220214..585e5fd1 100644
--- a/ios/RCTARKitManager.m
+++ b/ios/RCTARKitManager.m
@@ -51,6 +51,12 @@ - (NSDictionary *)constantsToExport
@"Screen": [@(SCNBlendModeScreen) stringValue],
@"Replace": [@(SCNBlendModeReplace) stringValue],
+ },
+ @"ChamferMode": @{
+ @"Both": [@(SCNChamferModeBoth) stringValue],
+ @"Back": [@(SCNChamferModeBack) stringValue],
+ @"Front": [@(SCNChamferModeBack) stringValue],
+
}
};
}
diff --git a/ios/RCTConvert+ARKit.h b/ios/RCTConvert+ARKit.h
index 0576ed06..7a122ce0 100644
--- a/ios/RCTConvert+ARKit.h
+++ b/ios/RCTConvert+ARKit.h
@@ -31,6 +31,7 @@
+ (SCNTorus *)SCNTorus:(id)json;
+ (SCNCapsule *)SCNCapsule:(id)json;
+ (SCNPlane *)SCNPlane:(id)json;
++ (SCNShape * )SCNShape:(id)json;
+ (SCNTextNode *)SCNTextNode:(id)json;
diff --git a/ios/RCTConvert+ARKit.m b/ios/RCTConvert+ARKit.m
index 91a22c24..ecc263ea 100644
--- a/ios/RCTConvert+ARKit.m
+++ b/ios/RCTConvert+ARKit.m
@@ -7,6 +7,7 @@
//
#import "RCTConvert+ARKit.h"
+#import "SVGBezierPath.h"
@implementation RCTConvert (ARKit)
@@ -37,10 +38,10 @@ + (SCNVector4)SCNVector4:(id)json {
+ (SCNNode *)SCNNode:(id)json {
SCNNode *node = [SCNNode new];
-
+
node.name = [NSString stringWithFormat:@"%@", json[@"id"]];
[self setNodeProperties:node properties:json];
-
+
return node;
}
@@ -51,10 +52,9 @@ + (SCNBox *)SCNBox:(id)json {
CGFloat length = [shape[@"length"] floatValue];
CGFloat chamfer = [shape[@"chamfer"] floatValue];
SCNBox *geometry = [SCNBox boxWithWidth:width height:height length:length chamferRadius:chamfer];
-
SCNMaterial *material = [self SCNMaterial:json[@"material"]];
geometry.materials = @[material, material, material, material, material, material];
-
+
return geometry;
}
@@ -65,7 +65,7 @@ + (SCNSphere *)SCNSphere:(id)json {
SCNMaterial *material = [self SCNMaterial:json[@"material"]];
geometry.materials = @[material];
-
+
return geometry;
}
@@ -131,7 +131,7 @@ + (SCNTorus *)SCNTorus:(id)json {
return geometry;
}
-
+
+ (SCNCapsule *)SCNCapsule:(id)json {
NSDictionary* shape = json[@"shape"];
CGFloat capR = [shape[@"capR"] floatValue];
@@ -167,6 +167,67 @@ + (SCNPlane *)SCNPlane:(id)json {
return geometry;
}
++ (SVGBezierPath *)svgStringToBezier:(NSString *)pathString {
+ NSArray * paths = [SVGBezierPath pathsFromSVGString:pathString];
+ SVGBezierPath * fullPath;
+ for(SVGBezierPath *path in paths) {
+ if(!fullPath) {
+ fullPath = path;
+ } else {
+ [fullPath appendPath:path];
+ }
+ }
+ return fullPath;
+}
+
++ (SCNShape * )SCNShape:(id)json {
+ NSDictionary* shape = json[@"shape"];
+ NSString * pathString = shape[@"pathSvg"];
+
+ SVGBezierPath * path = [self svgStringToBezier:pathString];
+
+ if (shape[@"pathFlatness"]) {
+ path.flatness = [shape[@"pathFlatness"] floatValue];
+ }
+ CGFloat extrusion = [shape[@"extrusion"] floatValue];
+ SCNShape *geometry = [SCNShape shapeWithPath:path extrusionDepth:extrusion];
+ if (shape[@"chamferMode"]) {
+ geometry.chamferMode = (SCNChamferMode) [shape[@"chamferMode"] integerValue];
+ }
+ if (shape[@"chamferRadius"]) {
+ geometry.chamferRadius = [shape[@"chamferRadius"] floatValue];
+ }
+
+ if (shape[@"chamferProfilePathSvg"]) {
+
+ SVGBezierPath * path = [self svgStringToBezier:shape[@"chamferProfilePathSvg"]];
+ if(shape[@"chamferProfilePathFlatness"]) {
+ path.flatness = [shape[@"chamferProfilePathFlatness"] floatValue];
+ }
+ // normalize path
+ CGRect boundingBox = path.bounds;
+ if(path.bounds.size.width !=0 && path.bounds.size.height != 0) {
+ CGFloat scaleX = 1/boundingBox.size.width;
+ CGFloat scaleY = scaleY = 1/boundingBox.size.height;
+
+ CGAffineTransform transform = CGAffineTransformMakeScale(scaleX, scaleY);
+ [path applyTransform:transform];
+ geometry.chamferProfile = path;
+ } else {
+ NSLog(@"Invalid chamferProfilePathFlatness");
+ }
+
+ }
+
+
+
+ SCNMaterial *material = [self SCNMaterial:json[@"material"]];
+ material.doubleSided = YES;
+
+ geometry.materials = @[material];
+ return geometry;
+}
+
+ (SCNTextNode *)SCNTextNode:(id)json {
// init SCNText
@@ -183,7 +244,7 @@ + (SCNTextNode *)SCNTextNode:(id)json {
CGFloat fontSize = [font[@"size"] floatValue];
CGFloat size = fontSize / 12;
SCNText *scnText = [SCNText textWithString:text extrusionDepth:depth / size];
-
+
scnText.flatness = 0.1;
// font
@@ -215,7 +276,7 @@ + (SCNTextNode *)SCNTextNode:(id)json {
SCNVector3 min = SCNVector3Zero;
SCNVector3 max = SCNVector3Zero;
[textNode getBoundingBoxMin:&min max:&max];
-
+
textNode.position = SCNVector3Make(-(min.x + max.x) / 2 * size,
-(min.y + max.y) / 2 * size,
-(min.z + max.z) / 2 * size);
@@ -257,7 +318,7 @@ + (void)setNodeProperties:(SCNNode *)node properties:(id)json {
} else {
[SCNTransaction setAnimationDuration:0.0];
}
-
+
} else {
[SCNTransaction setAnimationDuration:0.0];
}
@@ -265,6 +326,12 @@ + (void)setNodeProperties:(SCNNode *)node properties:(id)json {
node.position = [self SCNVector3:json[@"position"]];
}
+ if (json[@"scale"]) {
+ CGFloat scale = [json[@"scale"] floatValue];
+ node.scale = SCNVector3Make(scale, scale, scale);
+
+ }
+
if (json[@"eulerAngles"]) {
node.eulerAngles = [self SCNVector3:json[@"eulerAngles"]];
}
diff --git a/ios/components/ARGeosManager.m b/ios/components/ARGeosManager.m
index 754cc4b8..1157f35b 100644
--- a/ios/components/ARGeosManager.m
+++ b/ios/components/ARGeosManager.m
@@ -58,6 +58,11 @@ @implementation ARGeosManager
[[RCTARKitNodes sharedInstance] addNodeToScene:node inReferenceFrame:frame];
}
+RCT_EXPORT_METHOD(addShape:(SCNShape *)geometry node:(SCNNode *)node frame:(NSString *)frame) {
+ node.geometry = geometry;
+ [[RCTARKitNodes sharedInstance] addNodeToScene:node inReferenceFrame:frame];
+}
+
RCT_EXPORT_METHOD(unmount:(NSString *)identifier) {
[[RCTARKitNodes sharedInstance] removeNodeForKey:identifier];
}
diff --git a/package.json b/package.json
index a9bb2cf5..67b4f1e5 100644
--- a/package.json
+++ b/package.json
@@ -15,11 +15,12 @@
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
+ "_PocketSVG": "https://github.com/pocketsvg/PocketSVG",
"fast-deep-equal": "^1.0.0",
"lodash": "^4.17.4",
"prop-types": "^15.5.7",
"react": "16.0.0-alpha.12",
- "react-animation-frame": "^0.3.5"
+ "@panter/react-animation-frame": "^0.3.6"
},
"devDependencies": {
"babel-eslint": "^7.2.3",
diff --git a/yarn.lock b/yarn.lock
index 3655f102..30fd06b4 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,6 +2,10 @@
# yarn lockfile v1
+"_PocketSVG@https://github.com/pocketsvg/PocketSVG":
+ version "0.0.0"
+ resolved "https://github.com/pocketsvg/PocketSVG#e6d84ddeb11f99c4420e354ebb9fd34db2cf507a"
+
acorn-jsx@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b"