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

Rapid Cross-Platform AR Development with React Native

Rapid Cross-Platform AR Development with React Native

Augmented Reality's popularity is growing at an ever increasing rate, and it might seem as if native iOS and Android developers are the only ones who have the skills to keep up.

Fortunately, a platform called Viro was created to enable web and mobile developers to develop cross-platform AR/VR experiences through the React Native framework.

We'll take a brief look at what AR is and how it works, and then take a deep dive into Viro and everything it provides to get you moving rapidly with AR development.

We'll focus on a few very interesting pieces that Viro provides, such as 3D models, portals, image recognition, and real life object recognition.

By the end of this session, you will have the skills and inspiration to start working with AR immediately!

Alex Hinson

May 08, 2019
Tweet

More Decks by Alex Hinson

Other Decks in Technology

Transcript

  1. PID PID RA PID RA PID Cross Platform Cross Platform

    ATIVE ATIVE REACT NATIVE REACT NATIVE WITH WITH WITH WITH Alex Hinson n @amhinson
  2. PID PID RA PID RA PID Cross Platform Cross Platform

    ATIVE ATIVE REACT NATIVE REACT NATIVE WITH WITH WITH WITH Alex Hinson n @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

    setInternal 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']} /> ))