Skip to content

Commit

Permalink
fix #348: cursor position is incorrect when dragging ray pointer with…
Browse files Browse the repository at this point in the history
… pointer capture
  • Loading branch information
bbohlender committed Sep 10, 2024
1 parent f9e3747 commit 866f9de
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 152 deletions.
257 changes: 123 additions & 134 deletions examples/uikit/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,8 @@ import { useControls } from 'leva'
const store = createXRStore({
hand: {
teleportPointer: true,
rayPointer: {
cursorModel: { color: 'black' },
},
touchPointer: { cursorModel: { color: 'black' } },
},
controller: {
rayPointer: {
filter: () => false,
},
teleportPointer: true,
},
})
Expand All @@ -44,144 +37,140 @@ export function App() {
<XR store={store}>
<XROrigin visible={visible} />
<Environment preset="city" />
<XRLayer
dpr={4}
pixelWidth={512}
pixelHeight={512}
pointerEventsType={{ deny: 'grab' }}
position={[0, 1.5, -0.5]}
>
<Fullscreen>

<group pointerEventsType={{ deny: 'grab' }} position={[0, 1.5, -0.5]}>
<Root
dark={{ backgroundColor: 'rgb(31,41,55)' }}
flexDirection="column"
pixelSize={0.005}
height="auto"
maxHeight={200}
width="100%"
backgroundColor="rgb(255,255,255)"
borderRadius={8}
overflow="scroll"
>
<Container
dark={{ backgroundColor: 'rgb(31,41,55)' }}
flexDirection="column"
height="auto"
width="100%"
backgroundColor="rgb(255,255,255)"
borderRadius={8}
overflow="hidden"
dark={{ backgroundColor: 'rgb(55,65,81)' }}
display="flex"
justifyContent="space-between"
alignItems="center"
flexShrink={0}
borderTopLeftRadius={8}
borderTopRightRadius={8}
backgroundColor="rgb(243,244,246)"
paddingLeft={16}
paddingRight={16}
paddingTop={8}
paddingBottom={8}
>
<Container
dark={{ backgroundColor: 'rgb(55,65,81)' }}
display="flex"
justifyContent="space-between"
alignItems="center"
borderTopLeftRadius={8}
borderTopRightRadius={8}
backgroundColor="rgb(243,244,246)"
paddingLeft={16}
paddingRight={16}
paddingTop={8}
paddingBottom={8}
<Text
fontSize={18}
fontWeight={500}
lineHeight={28}
color="rgb(17,24,39)"
dark={{ color: 'rgb(243,244,246)' }}
flexDirection="column"
>
<Text
fontSize={18}
fontWeight={500}
lineHeight={28}
color="rgb(17,24,39)"
dark={{ color: 'rgb(243,244,246)' }}
flexDirection="column"
>
Music Player
</Text>
<Container display="flex" flexDirection="row" gapColumn={8}>
<ExpandIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
<ConstructionIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
<MenuIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
Music Player
</Text>
<Container display="flex" flexDirection="row" gapColumn={8}>
<ExpandIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
<ConstructionIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
<MenuIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
</Container>
</Container>
<Container flexShrink={0} display="flex" flexDirection="column" gapRow={16} padding={16}>
<Container display="flex" alignItems="center" flexDirection="row" gapColumn={16}>
<Image height={64} src="placeholder.svg" width={64} flexDirection="column"></Image>
<Container flexGrow={1} flexShrink={1} flexBasis="0%" flexDirection="column" gapRow={4}>
<Text
fontSize={18}
fontWeight={500}
lineHeight={28}
color="rgb(17,24,39)"
dark={{ color: 'rgb(243,244,246)' }}
flexDirection="column"
>
Blowin' in the Wind
</Text>
<Text
fontSize={14}
lineHeight={20}
color="rgb(107,114,128)"
dark={{ color: 'rgb(156,163,175)' }}
flexDirection="column"
>
Bob Dylan {counter.toString()}
</Text>
</Container>
</Container>
<Container display="flex" flexDirection="column" gapRow={16} padding={16}>
<Container display="flex" alignItems="center" flexDirection="row" gapColumn={16}>
<Image height={64} src="placeholder.svg" width={64} flexDirection="column"></Image>
<Container flexGrow={1} flexShrink={1} flexBasis="0%" flexDirection="column" gapRow={4}>
<Text
fontSize={18}
fontWeight={500}
lineHeight={28}
color="rgb(17,24,39)"
dark={{ color: 'rgb(243,244,246)' }}
flexDirection="column"
>
Blowin' in the Wind
</Text>
<Text
fontSize={14}
lineHeight={20}
color="rgb(107,114,128)"
dark={{ color: 'rgb(156,163,175)' }}
flexDirection="column"
>
Bob Dylan {counter.toString()}
</Text>
</Container>
<Slider />
<Container display="flex" alignItems="center" justifyContent="space-between">
<Button size="icon" variant="ghost">
<ArrowLeftIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
</Button>
<Button onClick={() => setCounter((c) => c + 1)} size="icon" variant="ghost" padding={8}>
<PlayIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
</Button>
<Button size="icon" variant="ghost">
<ArrowRightIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
</Button>
</Container>
</Container>
<Container flexShrink={0} padding={16} flexDirection="column">
<Text
fontSize={18}
fontWeight={500}
lineHeight={28}
color="rgb(17,24,39)"
dark={{ color: 'rgb(243,244,246)' }}
marginBottom={8}
flexDirection="column"
>
Playlist
</Text>
<Container flexDirection="column" gapRow={8}>
<Container display="flex" alignItems="center" justifyContent="space-between">
<Text
fontSize={14}
lineHeight={20}
color="rgb(17,24,39)"
dark={{ color: 'rgb(243,244,246)' }}
flexDirection="column"
>
Like a Rolling Stone
</Text>
<PlayIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
</Container>
<Slider />
<Container display="flex" alignItems="center" justifyContent="space-between">
<Button size="icon" variant="ghost">
<ArrowLeftIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
</Button>
<Button onClick={() => setCounter((c) => c + 1)} size="icon" variant="ghost" padding={8}>
<PlayIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
</Button>
<Button size="icon" variant="ghost">
<ArrowRightIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
</Button>
<Text
fontSize={14}
lineHeight={20}
color="rgb(17,24,39)"
dark={{ color: 'rgb(243,244,246)' }}
flexDirection="column"
>
The Times They Are a-Changin'
</Text>
<PlayIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
</Container>
</Container>
<Container padding={16} flexDirection="column">
<Text
fontSize={18}
fontWeight={500}
lineHeight={28}
color="rgb(17,24,39)"
dark={{ color: 'rgb(243,244,246)' }}
marginBottom={8}
flexDirection="column"
>
Playlist
</Text>
<Container flexDirection="column" gapRow={8}>
<Container display="flex" alignItems="center" justifyContent="space-between">
<Text
fontSize={14}
lineHeight={20}
color="rgb(17,24,39)"
dark={{ color: 'rgb(243,244,246)' }}
flexDirection="column"
>
Like a Rolling Stone
</Text>
<PlayIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
</Container>
<Container display="flex" alignItems="center" justifyContent="space-between">
<Text
fontSize={14}
lineHeight={20}
color="rgb(17,24,39)"
dark={{ color: 'rgb(243,244,246)' }}
flexDirection="column"
>
The Times They Are a-Changin'
</Text>
<PlayIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
</Container>
<Container display="flex" alignItems="center" justifyContent="space-between">
<Text
fontSize={14}
lineHeight={20}
color="rgb(17,24,39)"
dark={{ color: 'rgb(243,244,246)' }}
flexDirection="column"
>
Subterranean Homesick Blues
</Text>
<PlayIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
</Container>
<Container display="flex" alignItems="center" justifyContent="space-between">
<Text
fontSize={14}
lineHeight={20}
color="rgb(17,24,39)"
dark={{ color: 'rgb(243,244,246)' }}
flexDirection="column"
>
Subterranean Homesick Blues
</Text>
<PlayIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
</Container>
</Container>
</Container>
</Fullscreen>
</XRLayer>
</Root>
</group>
</XR>
</Canvas>
</>
Expand Down
6 changes: 3 additions & 3 deletions examples/uikit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
"dependencies": {
"@pmndrs/pointer-events": "workspace:^",
"@react-three/drei": "^9.108.3",
"@react-three/uikit": "^0.4.0",
"@react-three/uikit-default": "^0.4.0",
"@react-three/uikit-lucide": "^0.4.0",
"@react-three/uikit": "^0.5.3",
"@react-three/uikit-default": "^0.5.3",
"@react-three/uikit-lucide": "^0.5.3",
"@react-three/xr": "workspace:^",
"leva": "^0.9.35"
},
Expand Down
3 changes: 1 addition & 2 deletions packages/pointer-events/src/intersections/ray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,11 @@ export class CameraRayIntersector extends Intersector {
}

computeIntersectionWorldPlane(this.viewPlane, intersection, object)
const pointOnFace = this.raycaster.ray.intersectPlane(this.viewPlane, new Vector3()) ?? point
return {
...intersection,
object,
point,
pointOnFace,
pointOnFace: point,
pointerPosition: this.fromPosition.clone(),
pointerQuaternion: this.fromQuaternion.clone(),
}
Expand Down
6 changes: 3 additions & 3 deletions packages/pointer-events/src/intersections/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { Plane, Intersection as ThreeIntersection, Object3D } from 'three'
import { Intersection, IntersectionOptions } from './index.js'
import { AllowedPointerEventsType, Pointer, type AllowedPointerEvents } from '../pointer.js'
import { hasObjectListeners } from '../utils.js'
import { CombinedPointer } from '../index.js'

export function computeIntersectionWorldPlane(target: Plane, intersection: Intersection, object: Object3D): boolean {
if (intersection.face == null) {
const normal = intersection.normal ?? intersection.face?.normal
if (normal == null) {
return false
}
target.setFromNormalAndCoplanarPoint(intersection.face.normal, intersection.localPoint)
target.setFromNormalAndCoplanarPoint(normal, intersection.localPoint)
target.applyMatrix4(object.matrixWorld)
return true
}
Expand Down
33 changes: 23 additions & 10 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 866f9de

Please sign in to comment.