diff --git a/README.md b/README.md index be9178c2..d98c29a7 100644 --- a/README.md +++ b/README.md @@ -270,16 +270,16 @@ E.g. you can scale an object on unmount: /> ``` -#### Material properties +#### Material Most objects take a material property with these sub-props: | Prop | Type | Description | |---|---|---| -| `diffuse` | { `path`, `color`, `intensity` } | [diffuse](https://developer.apple.com/documentation/scenekit/scnmaterial/1462589-diffuse?language=objc) -| `specular` | { `path`, `color`, `intensity` } | [specular](https://developer.apple.com/documentation/scenekit/scnmaterial/1462516-specular?language=objc) -| `displacement` | { `path`, `color`, `intensity` } | [displacement](https://developer.apple.com/documentation/scenekit/scnmaterial/2867516-displacement?language=objc) -| `normal` | { `path`, `color`, `intensity` } | [normal](https://developer.apple.com/documentation/scenekit/scnmaterial/1462542-normal) +| `diffuse` | `{ ...mapProperties }` (see below) | [diffuse](https://developer.apple.com/documentation/scenekit/scnmaterial/1462589-diffuse?language=objc) +| `specular` | `{ ...mapProperties }` (see below) | [specular](https://developer.apple.com/documentation/scenekit/scnmaterial/1462516-specular?language=objc) +| `displacement` | `{ ...mapProperties }` (see below) | [displacement](https://developer.apple.com/documentation/scenekit/scnmaterial/2867516-displacement?language=objc) +| `normal` | `{ ...mapProperties }` (see below) | [normal](https://developer.apple.com/documentation/scenekit/scnmaterial/1462542-normal) | `metalness` | number | metalness of the object | | `roughness` | number | roughness of the object | | `doubleSided` | boolean | render both sides, default is `true` | @@ -290,7 +290,18 @@ Most objects take a material property with these sub-props: | `shaders` | Object with keys from `ARKit.ShaderModifierEntryPoint.*` and shader strings as values | [Shader modifiers](https://developer.apple.com/documentation/scenekit/scnshadable) | | `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. | +Map Properties: +| Prop | Type | Description | +|---|---|---| +| `path` | string | Currently `require` is not supported, so this is an absolute link to a local resource placed for example in .xcassets | +| `color` | string | Color string, only used if path is not provided | +| `wrapS` | `ARKit.WrapMode.{ Clamp \| Repeat \| Mirror }` | [wrapS](https://developer.apple.com/documentation/scenekit/scnmaterialproperty/1395384-wraps?language=objc) | +| `wrapT` | `ARKit.WrapMode.{ Clamp \| Repeat \| Mirror }` |  [wrapT](https://developer.apple.com/documentation/scenekit/scnmaterialproperty/1395382-wrapt?language=objc) | +| `wrap` | `ARKit.WrapMode.{ Clamp \| Repeat \| Mirror }` |  Shorthand for setting both wrapS & wrapT | +| `translation` | `{ x, y, z }` | Translate the UVs, equivalent to applying a translation matrix to SceneKit's `transformContents` | +| `rotation` | `{ angle, x, y, z }` | Rotate the UVs, equivalent to applying a rotation matrix to SceneKit's `transformContents` | +| `scale` | `{ x, y, z }` | Scale the UVs, equivalent to applying a scale matrix to SceneKit's `transformContents` | diff --git a/components/lib/propTypes.js b/components/lib/propTypes.js index 33aa92ae..d936ae91 100644 --- a/components/lib/propTypes.js +++ b/components/lib/propTypes.js @@ -39,6 +39,25 @@ export const orientation = PropTypes.shape({ w: animatableNumber, }); +export const textureTranslation = PropTypes.shape({ + x: PropTypes.number, + y: PropTypes.number, + z: PropTypes.number, +}); + +export const textureRotation = PropTypes.shape({ + angle: PropTypes.number, + x: PropTypes.number, + y: PropTypes.number, + z: PropTypes.number, +}); + +export const textureScale = PropTypes.shape({ + x: PropTypes.number, + y: PropTypes.number, + z: PropTypes.number, +}); + export const shaders = PropTypes.shape({ [ARKitManager.ShaderModifierEntryPoint.Geometry]: PropTypes.string, [ARKitManager.ShaderModifierEntryPoint.Surface]: PropTypes.string, @@ -65,10 +84,18 @@ export const colorBufferWriteMask = PropTypes.oneOf( export const opacity = animatableNumber; +export const wrapMode = PropTypes.oneOf(values(ARKitManager.WrapMode)); + export const materialProperty = PropTypes.shape({ path: PropTypes.string, color: PropTypes.string, intensity: PropTypes.number, + wrapS: wrapMode, + wrapT: wrapMode, + wrap: wrapMode, + translation: textureTranslation, + scale: textureScale, + rotation: textureRotation, }); export const material = PropTypes.shape({ diff --git a/ios/RCTARKitManager.m b/ios/RCTARKitManager.m index f1f25c5c..a5ff7d83 100644 --- a/ios/RCTARKitManager.m +++ b/ios/RCTARKitManager.m @@ -97,6 +97,11 @@ - (NSDictionary *)constantsToExport @"FillMode": @{ @"Fill": [@(SCNFillModeFill) stringValue], @"Lines": [@(SCNFillModeLines) stringValue], + }, + @"WrapMode": @{ + @"Clamp": [@(SCNWrapModeClamp) stringValue], + @"Repeat": [@(SCNWrapModeRepeat) stringValue], + @"Mirror": [@(SCNWrapModeMirror) stringValue], } }; } diff --git a/ios/RCTConvert+ARKit.m b/ios/RCTConvert+ARKit.m index d5de35a0..257085d5 100644 --- a/ios/RCTConvert+ARKit.m +++ b/ios/RCTConvert+ARKit.m @@ -306,8 +306,52 @@ + (SCNLight *)SCNLight:(id)json { + (void)setMaterialPropertyContents:(id)property material:(SCNMaterialProperty *)material { + if (property[@"path"]) { + SCNMatrix4 m = SCNMatrix4Identity; material.contents = property[@"path"]; + + if (property[@"wrapS"]) { + material.wrapS = (SCNWrapMode) [property[@"wrapS"] integerValue]; + } + + if (property[@"wrapT"]) { + material.wrapT = (SCNWrapMode) [property[@"wrapT"] integerValue]; + } + + if (property[@"wrap"]) { + material.wrapT = (SCNWrapMode) [property[@"wrapT"] integerValue]; + material.wrapS = (SCNWrapMode) [property[@"wrapS"] integerValue]; + } + + if (property[@"translation"]) { + float x = [property[@"translation"][@"x"] floatValue]; + float y = [property[@"translation"][@"y"] floatValue]; + float z = [property[@"translation"][@"z"] floatValue]; + + m = SCNMatrix4Mult(m, SCNMatrix4MakeTranslation(x, y, z)); + } + + if (property[@"rotation"]) { + float a = [property[@"rotation"][@"angle"] floatValue]; + float x = [property[@"rotation"][@"x"] floatValue]; + float y = [property[@"rotation"][@"y"] floatValue]; + float z = [property[@"rotation"][@"z"] floatValue]; + + m = SCNMatrix4Mult(m, SCNMatrix4MakeRotation(a, x, y, z)); + } + + if (property[@"scale"]) { + float x = [property[@"scale"][@"x"] floatValue]; + float y = [property[@"scale"][@"y"] floatValue]; + float z = [property[@"scale"][@"z"] floatValue]; + + m = SCNMatrix4Mult(m, SCNMatrix4MakeScale(x, y, z)); + } + + material.contentsTransform = m; + + } else if (property[@"color"]) { material.contents = [self UIColor:property[@"color"]]; }