Skip to content

Commit d5de1b1

Browse files
authored
Merge pull request #121 from archilogic-com/custom-maps
Implement basic support for adding maps to SCNMaterial
2 parents b64cd78 + 8cae9ff commit d5de1b1

File tree

6 files changed

+88
-48
lines changed

6 files changed

+88
-48
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,10 @@ Most objects take a material property with these sub-props:
244244

245245
| Prop | Type | Description |
246246
|---|---|---|
247-
| `diffuse` | colorstring | diffuse color |
247+
| `diffuse` | { `path`, `color`, `intensity` } | [diffuse](https://developer.apple.com/documentation/scenekit/scnmaterial/1462589-diffuse?language=objc)
248+
| `specular` | { `path`, `color`, `intensity` } | [specular](https://developer.apple.com/documentation/scenekit/scnmaterial/1462516-specular?language=objc)
249+
| `displacement` | { `path`, `color`, `intensity` } | [displacement](https://developer.apple.com/documentation/scenekit/scnmaterial/2867516-displacement?language=objc)
250+
| `normal` | { `path`, `color`, `intensity` } | [normal](https://developer.apple.com/documentation/scenekit/scnmaterial/1462542-normal)
248251
| `metalness` | number | metalness of the object |
249252
| `roughness` | number | roughness of the object |
250253
| `doubleSided` | boolean | render both sides, default is `true` |

components/lib/createArComponent.js

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Component } from 'react';
2-
import { NativeModules } from 'react-native';
2+
import { NativeModules, processColor } from 'react-native';
33
import PropTypes from 'prop-types';
44
import filter from 'lodash/filter';
55
import isDeepEqual from 'fast-deep-equal';
@@ -20,7 +20,7 @@ import {
2020
scale,
2121
transition,
2222
} from './propTypes';
23-
import { processColor, processColorInMaterial } from './parseColor';
23+
import processMaterial from './processMaterial';
2424
import generateId from './generateId';
2525

2626
const { ARGeosManager } = NativeModules;
@@ -69,20 +69,17 @@ export default (mountConfig, propTypes = {}, nonUpdateablePropKeys = []) => {
6969
// any custom props (material, shape, ...)
7070
const nonNodePropKeys = keys(propTypes);
7171

72-
const processColors = props => ({
72+
const parseMaterials = props => ({
7373
...props,
74-
...(props.color ? { color: processColor(props.color) } : {}),
7574
...(props.shadowColor
7675
? { shadowColor: processColor(props.shadowColor) }
7776
: {}),
78-
...(props.material
79-
? { material: processColorInMaterial(props.material) }
80-
: {}),
77+
...(props.material ? { material: processMaterial(props.material) } : {}),
8178
});
8279

8380
const getNonNodeProps = props => ({
8481
...pick(props, nonNodePropKeys),
85-
...processColors(props),
82+
...parseMaterials(props),
8683
});
8784

8885
const mountFunc =
@@ -158,7 +155,7 @@ export default (mountConfig, propTypes = {}, nonUpdateablePropKeys = []) => {
158155
...this.props.transition,
159156
...props.transition,
160157
},
161-
...processColors(pick(props, changedKeys)),
158+
...parseMaterials(pick(props, changedKeys)),
162159
};
163160

164161
if (DEBUG) console.log('update node', propsToupdate);

components/lib/parseColor.js

Lines changed: 0 additions & 19 deletions
This file was deleted.

components/lib/processMaterial.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { processColor } from 'react-native';
2+
import { isString, mapValues, set } from 'lodash';
3+
4+
// https://developer.apple.com/documentation/scenekit/scnmaterial
5+
const propsWithMaps = ['normal', 'diffuse', 'displacement', 'specular'];
6+
7+
export default function processMaterial(material) {
8+
// previously it was possible to set { material: { color:'colorstring'}}... translate this to { material: { diffuse: { color: 'colorstring'}}}
9+
if (material.color) {
10+
set(material, 'diffuse.color', material.color);
11+
}
12+
13+
return mapValues(
14+
material,
15+
(prop, key) =>
16+
propsWithMaps.includes(key)
17+
? {
18+
...prop,
19+
color: processColor(
20+
// allow for setting a diffuse colorstring { diffuse: 'colorstring'}
21+
key === 'diffuse' && isString(prop) ? prop : prop.color,
22+
),
23+
}
24+
: prop,
25+
);
26+
}

components/lib/propTypes.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,18 @@ export const colorBufferWriteMask = PropTypes.oneOf(
6161

6262
export const opacity = PropTypes.number;
6363

64+
export const materialProperty = PropTypes.shape({
65+
path: PropTypes.string,
66+
color: PropTypes.string,
67+
intensity: PropTypes.number,
68+
});
69+
6470
export const material = PropTypes.shape({
6571
color,
72+
normal: materialProperty,
73+
specular: materialProperty,
74+
displacement: materialProperty,
75+
diffuse: PropTypes.oneOfType([PropTypes.string, materialProperty]),
6676
metalness: PropTypes.number,
6777
roughness: PropTypes.number,
6878
blendMode,

ios/RCTConvert+ARKit.m

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -187,24 +187,24 @@ + (SVGBezierPath *)svgStringToBezier:(NSString *)pathString {
187187

188188
+ (void)setChamferProfilePathSvg:(SCNShape *)geometry properties:(NSDictionary *)shape {
189189
if (shape[@"chamferProfilePathSvg"]) {
190-
191-
192-
SVGBezierPath * path = [self svgStringToBezier:shape[@"chamferProfilePathSvg"]];
193-
if(shape[@"chamferProfilePathFlatness"]) {
194-
path.flatness = [shape[@"chamferProfilePathFlatness"] floatValue];
195-
}
196-
// normalize path
197-
CGRect boundingBox = path.bounds;
198-
if(path.bounds.size.width !=0 && path.bounds.size.height != 0) {
199-
CGFloat scaleX = 1/boundingBox.size.width;
200-
CGFloat scaleY = scaleY = 1/boundingBox.size.height;
201190

202-
CGAffineTransform transform = CGAffineTransformMakeScale(scaleX, scaleY);
203-
[path applyTransform:transform];
204-
geometry.chamferProfile = path;
205-
} else {
206-
NSLog(@"Invalid chamferProfilePathFlatness");
207-
}
191+
192+
SVGBezierPath * path = [self svgStringToBezier:shape[@"chamferProfilePathSvg"]];
193+
if(shape[@"chamferProfilePathFlatness"]) {
194+
path.flatness = [shape[@"chamferProfilePathFlatness"] floatValue];
195+
}
196+
// normalize path
197+
CGRect boundingBox = path.bounds;
198+
if(path.bounds.size.width !=0 && path.bounds.size.height != 0) {
199+
CGFloat scaleX = 1/boundingBox.size.width;
200+
CGFloat scaleY = scaleY = 1/boundingBox.size.height;
201+
202+
CGAffineTransform transform = CGAffineTransformMakeScale(scaleX, scaleY);
203+
[path applyTransform:transform];
204+
geometry.chamferProfile = path;
205+
} else {
206+
NSLog(@"Invalid chamferProfilePathFlatness");
207+
}
208208
}
209209

210210
}
@@ -305,6 +305,17 @@ + (SCNLight *)SCNLight:(id)json {
305305
}
306306

307307

308+
+ (void)setMaterialPropertyContents:(id)property material:(SCNMaterialProperty *)material {
309+
if (property[@"path"]) {
310+
material.contents = property[@"path"];
311+
} else if (property[@"color"]) {
312+
material.contents = [self UIColor:property[@"color"]];
313+
}
314+
if (property[@"intensity"]) {
315+
material.intensity = [property[@"intensity"] floatValue];
316+
}
317+
}
318+
308319
+ (void)setMaterialProperties:(SCNMaterial *)material properties:(id)json {
309320
if (json[@"doubleSided"]) {
310321
material.doubleSided = [json[@"doubleSided"] boolValue];
@@ -321,8 +332,21 @@ + (void)setMaterialProperties:(SCNMaterial *)material properties:(id)json {
321332
}
322333

323334
if (json[@"diffuse"]) {
324-
material.diffuse.contents = [self UIColor:json[@"diffuse"]];
335+
[self setMaterialPropertyContents:json[@"diffuse"] material:material.diffuse];
336+
}
337+
338+
if (json[@"normal"]) {
339+
[self setMaterialPropertyContents:json[@"normal"] material:material.normal];
340+
}
341+
342+
if (json[@"displacement"]) {
343+
[self setMaterialPropertyContents:json[@"displacement"] material:material.displacement];
344+
}
345+
346+
if (json[@"specular"]) {
347+
[self setMaterialPropertyContents:json[@"specular"] material:material.specular];
325348
}
349+
326350
if (json[@"transparency"]) {
327351
material.transparency = [json[@"transparency"] floatValue];
328352
}
@@ -357,7 +381,6 @@ + (void)setMaterialProperties:(SCNMaterial *)material properties:(id)json {
357381
material.doubleSided = [json[@"doubleSided"] boolValue];
358382
}
359383

360-
361384
if(json[@"litPerPixel"]) {
362385
material.litPerPixel = [json[@"litPerPixel"] boolValue];
363386
}

0 commit comments

Comments
 (0)