Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rapid Cross-Platform AR Development with React ...

Rapid Cross-Platform AR Development with React Native

Alex Hinson

October 04, 2019
Tweet

More Decks by Alex Hinson

Other Decks in Technology

Transcript

  1. RA PID RA PID RA PID RA PID m m

    Cross Platform Cross Platform EACT NATIVE EACT NATIVE REACT NATIVE REACT NATIVE WITH WITH WITH WITH son Alex Hinson amhinson @amhinson
  2. RA PID RA PID RA PID RA PID m m

    Cross Platform Cross Platform EACT NATIVE EACT NATIVE REACT NATIVE REACT NATIVE WITH WITH WITH WITH son Alex Hinson amhinson @amhinson
  3. creates a virtual environment that is closed off to the

    real world places virtual objects in the real world
  4. <ViroSphere radius={0.2} materials={['moon']} /> // ... ViroMaterials.createMaterials({ moon: { shininess:

    2.0, lightingModel: 'Blinn', diffuseTexture: require('./res/moon.jpg') } });
  5. <ViroSphere radius={0.2} onDrag={position => this.setState({ x: position[0], y: position[1], z:

    position[2] }) } position={[this.state.x, this.state.y, this.state.z]} materials={['moon']} />
  6. <ViroSphere radius={0.2} onDrag={position => this.setState({ x: position[0], y: position[1], z:

    position[2] }) } position={[this.state.x, this.state.y, this.state.z]} materials={['moon']} animation={{ name: 'spin', run: true, loop: true }} />
  7. final ARScene scene = new ARScene(); scene.setListener(new ARScene.Listener() { public

    void onAnchorFound(ARAnchor anchor, ARNode arNode) { // Make sure anchor is a plane if (anchor.getType() == ARAnchor.Typea.PLANE) { ARPlaneAnchor planeAnchor = (ARPlaneAnchor) anchor; // Ensure this is a horizontal plane of the right size if (planeAnchor.getAlignment() == ARPlaneAnchor.Alignment.HORIZONTAL && planeAnchor.getWidth() > 1.0 && planeAnchor.getHeight() > 1.0) { Object3D dinosaur = new Object3D(); dinosaur.loadModel("file://android-asset/dinosaur.fbx", Object3D.Type.FBS); arNode.addChildNode(dinosaur); } } } });
  8. <ViroSpotLight innerAngle={5} outerAngle={45} direction={[0, -1, -0.2]} position={[0, 3, 1]} color="#ffffff"

    castsShadow={true} shadowOpacity={0.5} /> // ... Viro3DObject <ViroQuad rotation={[-90, 0, 0]} width={4} height={4} arShadowReceiver={true} />
  9. <Viro3DObject source={require('./res/dino.vrx')} position={[0, 0, 0]} scale={[0.1, 0.1, 0.1]} type="VRX" onClick={()

    => this.setState({ runAnimation: true }) } animation={{ name: 'move', run: this.state.runAnimation, loop: true }} />
  10. <ViroPortalScene passable={true}> <ViroPortal position={[0, 0, -1]} scale={[0.1, 0.1, 0.1]} >

    <Viro3DObject source={require(‘./res/ship_window.vrx')} type="VRX" /> </ViroPortal> <Viro360Image source={require(‘./res/360_island.jpg')} /> </ViroPortalScene>
  11. <ViroARImageMarker target="airshipLogo" onAnchorFound={() => this.setState({ runAnimation: true }) } >

    // ... Objects to render when target is found </ViroARImageMarker>
  12. ViroAnimations.registerAnimations({ slideUp: { properties: { positionZ: 0, opacity: 1.0 },

    easing: 'Bounce', duration: 700 }, rotate: { properties: { rotateZ: '+=45' }, duration: 200 } });
  13. <ViroNode opacity={0} position={[0, -0.01, 0.05]} animation={{ name: ‘slideUp', run: this.state.runAnimation

    }} > <ViroText text="Airship" extrusionDepth={2} scale={[0.1, 0.1, 0.1]} rotation={[-90, 0, 0]} animation={{ name: 'rotate', run: this.state.runAnimation, loop: true }} /> </ViroNode>
  14. <ViroARImageMarker target="airshipLogo" onAnchorFound={() => this.setState({ runAnimation: true })}> <ViroNode opacity={0}

    position={[0, -0.01, 0.05]} animation={{ name: ‘slideUp', run: this.state.runAnimation }}> <ViroText text="Airship" extrusionDepth={2} scale={[0.1, 0.1, 0.1]} rotation={[-90, 0, 0]} animation={{ name: ‘rotate', run: this.state.runAnimation, loop: true }} /> </ViroNode> </ViroARImageMarker> // … ViroARTrackingTargets.createTargets({ airshipLogo: { source: require('./res/mark_with_bg.png'), orientation: 'Up', physicalWidth: 0.03 } }); ViroAnimations.registerAnimations({ slideUp: { properties: { positionZ: 0, opacity: 1.0 }, easing: 'Bounce', duration: 700 }, rotate: { properties: { rotateZ: ‘+=45' }, duration: 200 } });
  15. <ViroARObjectMarker target={target.targetName}> // ... Something to render </ViroARObjectMarker> // ...

    ViroARTrackingTargets.createTargets({ tvRemote: { source: require('./res/tvRemote.arobject'), type: 'Object' }, dvdRemote: { source: require('./res/dvdRemote.arobject'), type: 'Object' } });
  16. const TARGETS = [ { displayText: 'TV', targetName: 'tvRemote' },

    { displayText: 'DVD', targetName: 'dvdRemote' } ]; // ... {TARGETS.map(target => ( <ViroARObjectMarker target={target.targetName}> <ViroText text={target.displayText} extrusionDepth={2} scale={[0.15, 0.15, 0.15]} position={[0, 0.1, 0]} textAlign="center" /> </ViroARObjectMarker> ))}
  17. <View style={{ flex: 1 }}> <ViroARSceneNavigator apiKey={API_KEY} initialScene={{ scene: this.renderARScene

    }} /> <Text>Score: {this.state.score}</Text> <TouchableOpacity onPress={this.restartGame}> <Text>Restart</Text> </TouchableOpacity> </View>
  18. state = { dollarBills: [] }; // ... // Inside

    setInterval this.setState(({ dollarBills }) => ({ dollarBills: [ ...dollarBills, { position: this.randomXYZNumber(-2, 2), rotation: this.randomXYZNumber(-45, 45) } ] }));
  19. dollarBills.map((item, index) => ( <ViroBox key={index} position={item.position} rotation={item.rotation} onClick={() =>

    this.onDollarSelected(index)} height={0.2} length={0.01} width={0.6} materials={['billFace']} /> ))