react-native-ar / react-native-arkit

React Native binding for iOS ARKit
MIT License
1.73k stars 139 forks source link

Petition to add the following example to the repo #205

Open joseocasioserra opened 5 years ago

joseocasioserra commented 5 years ago

Hi,

I have used the library for the last couple of weeks and built and pretty interesting application. I would like share some code that will benefit most of the people using the library on object manipulation; specifically tapping on any object rendered and moving it around at will

objectToMove = ''

    constructor(props) {
        super(props)

        this.state = {
            objects: [], //add objects or models here
            tapPosition: {x: 0, y: 0, z: 0},
            objectId: ''
        }
    }

handleResponderMove = (e) => {
        this.hitTest({ x: e.nativeEvent.pageX, y: e.nativeEvent.pageY })
    }

    hitTest = async (location) => {
        const hits = await ARKit.hitTestPlanes(location, 1)
        const result = await ARKit.hitTestSceneObjects(location);

        // Detect hit on object
        if (result.results.length) {
            let id = result.results[0].id
            this.state.objects.forEach((element) => {
                if (element.props.id === id){   
                    this.objectToMove = id
                }
            })
        }

        // Update position on plane hit
        if (hits.results.length) {
            let x = hits.results[0].position.x * 10
            let y = hits.results[0].position.y * 10
            let z = hits.results[0].position.z * 10
            let pos = { x: x, y: y, z: z };

            this.setState({
                tapPosition: pos
            })
        }

renderElements = () => {
        return this.state.objects.map(element => {
            if (element.props.id === this.objectToMove){
                console.log(element)
                element.props.position.x = this.state.tapPosition.x
                element.props.position.y = this.state.tapPosition.y
                element.props.position.z = this.state.tapPosition.z
                element.props.eulerAngles.y = this.state.rotationY
                return element
            }
            else {
                return element   
            }
        })

 <View
                    style={{flex: 1}}
                    onResponderMove={this.handleResponderMove.bind(this)}
                    onStartShouldSetResponder={() => true}
                    onMoveShouldSetResponder={() => false}
                >
                    <ARKit
                        style={{ flex: 1 }}
                        planeDetection={ARKit.ARPlaneDetection.Horizontal}
                        lightEstimationEnabled
                    >
                        <ARKit.Group position={{ x: 0, y: 0, z: 0 }} scale={0.1}>
                            {this.renderElements()}                            
                        </ARKit.Group>
                        <ARKit.Light
                            position={{ x: 0, y: 15, z: 40 }}
                            type={ARKit.LightType.Omni}
                            color="white"
                        />
                    </ARKit>
</View>