Skip to content

Commit 866f9de

Browse files
committed
fix #348: cursor position is incorrect when dragging ray pointer with pointer capture
1 parent f9e3747 commit 866f9de

File tree

5 files changed

+153
-152
lines changed

5 files changed

+153
-152
lines changed

examples/uikit/app.tsx

+123-134
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,8 @@ import { useControls } from 'leva'
1818
const store = createXRStore({
1919
hand: {
2020
teleportPointer: true,
21-
rayPointer: {
22-
cursorModel: { color: 'black' },
23-
},
24-
touchPointer: { cursorModel: { color: 'black' } },
2521
},
2622
controller: {
27-
rayPointer: {
28-
filter: () => false,
29-
},
3023
teleportPointer: true,
3124
},
3225
})
@@ -44,144 +37,140 @@ export function App() {
4437
<XR store={store}>
4538
<XROrigin visible={visible} />
4639
<Environment preset="city" />
47-
<XRLayer
48-
dpr={4}
49-
pixelWidth={512}
50-
pixelHeight={512}
51-
pointerEventsType={{ deny: 'grab' }}
52-
position={[0, 1.5, -0.5]}
53-
>
54-
<Fullscreen>
40+
41+
<group pointerEventsType={{ deny: 'grab' }} position={[0, 1.5, -0.5]}>
42+
<Root
43+
dark={{ backgroundColor: 'rgb(31,41,55)' }}
44+
flexDirection="column"
45+
pixelSize={0.005}
46+
height="auto"
47+
maxHeight={200}
48+
width="100%"
49+
backgroundColor="rgb(255,255,255)"
50+
borderRadius={8}
51+
overflow="scroll"
52+
>
5553
<Container
56-
dark={{ backgroundColor: 'rgb(31,41,55)' }}
57-
flexDirection="column"
58-
height="auto"
59-
width="100%"
60-
backgroundColor="rgb(255,255,255)"
61-
borderRadius={8}
62-
overflow="hidden"
54+
dark={{ backgroundColor: 'rgb(55,65,81)' }}
55+
display="flex"
56+
justifyContent="space-between"
57+
alignItems="center"
58+
flexShrink={0}
59+
borderTopLeftRadius={8}
60+
borderTopRightRadius={8}
61+
backgroundColor="rgb(243,244,246)"
62+
paddingLeft={16}
63+
paddingRight={16}
64+
paddingTop={8}
65+
paddingBottom={8}
6366
>
64-
<Container
65-
dark={{ backgroundColor: 'rgb(55,65,81)' }}
66-
display="flex"
67-
justifyContent="space-between"
68-
alignItems="center"
69-
borderTopLeftRadius={8}
70-
borderTopRightRadius={8}
71-
backgroundColor="rgb(243,244,246)"
72-
paddingLeft={16}
73-
paddingRight={16}
74-
paddingTop={8}
75-
paddingBottom={8}
67+
<Text
68+
fontSize={18}
69+
fontWeight={500}
70+
lineHeight={28}
71+
color="rgb(17,24,39)"
72+
dark={{ color: 'rgb(243,244,246)' }}
73+
flexDirection="column"
7674
>
77-
<Text
78-
fontSize={18}
79-
fontWeight={500}
80-
lineHeight={28}
81-
color="rgb(17,24,39)"
82-
dark={{ color: 'rgb(243,244,246)' }}
83-
flexDirection="column"
84-
>
85-
Music Player
86-
</Text>
87-
<Container display="flex" flexDirection="row" gapColumn={8}>
88-
<ExpandIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
89-
<ConstructionIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
90-
<MenuIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
75+
Music Player
76+
</Text>
77+
<Container display="flex" flexDirection="row" gapColumn={8}>
78+
<ExpandIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
79+
<ConstructionIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
80+
<MenuIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
81+
</Container>
82+
</Container>
83+
<Container flexShrink={0} display="flex" flexDirection="column" gapRow={16} padding={16}>
84+
<Container display="flex" alignItems="center" flexDirection="row" gapColumn={16}>
85+
<Image height={64} src="placeholder.svg" width={64} flexDirection="column"></Image>
86+
<Container flexGrow={1} flexShrink={1} flexBasis="0%" flexDirection="column" gapRow={4}>
87+
<Text
88+
fontSize={18}
89+
fontWeight={500}
90+
lineHeight={28}
91+
color="rgb(17,24,39)"
92+
dark={{ color: 'rgb(243,244,246)' }}
93+
flexDirection="column"
94+
>
95+
Blowin' in the Wind
96+
</Text>
97+
<Text
98+
fontSize={14}
99+
lineHeight={20}
100+
color="rgb(107,114,128)"
101+
dark={{ color: 'rgb(156,163,175)' }}
102+
flexDirection="column"
103+
>
104+
Bob Dylan {counter.toString()}
105+
</Text>
91106
</Container>
92107
</Container>
93-
<Container display="flex" flexDirection="column" gapRow={16} padding={16}>
94-
<Container display="flex" alignItems="center" flexDirection="row" gapColumn={16}>
95-
<Image height={64} src="placeholder.svg" width={64} flexDirection="column"></Image>
96-
<Container flexGrow={1} flexShrink={1} flexBasis="0%" flexDirection="column" gapRow={4}>
97-
<Text
98-
fontSize={18}
99-
fontWeight={500}
100-
lineHeight={28}
101-
color="rgb(17,24,39)"
102-
dark={{ color: 'rgb(243,244,246)' }}
103-
flexDirection="column"
104-
>
105-
Blowin' in the Wind
106-
</Text>
107-
<Text
108-
fontSize={14}
109-
lineHeight={20}
110-
color="rgb(107,114,128)"
111-
dark={{ color: 'rgb(156,163,175)' }}
112-
flexDirection="column"
113-
>
114-
Bob Dylan {counter.toString()}
115-
</Text>
116-
</Container>
108+
<Slider />
109+
<Container display="flex" alignItems="center" justifyContent="space-between">
110+
<Button size="icon" variant="ghost">
111+
<ArrowLeftIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
112+
</Button>
113+
<Button onClick={() => setCounter((c) => c + 1)} size="icon" variant="ghost" padding={8}>
114+
<PlayIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
115+
</Button>
116+
<Button size="icon" variant="ghost">
117+
<ArrowRightIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
118+
</Button>
119+
</Container>
120+
</Container>
121+
<Container flexShrink={0} padding={16} flexDirection="column">
122+
<Text
123+
fontSize={18}
124+
fontWeight={500}
125+
lineHeight={28}
126+
color="rgb(17,24,39)"
127+
dark={{ color: 'rgb(243,244,246)' }}
128+
marginBottom={8}
129+
flexDirection="column"
130+
>
131+
Playlist
132+
</Text>
133+
<Container flexDirection="column" gapRow={8}>
134+
<Container display="flex" alignItems="center" justifyContent="space-between">
135+
<Text
136+
fontSize={14}
137+
lineHeight={20}
138+
color="rgb(17,24,39)"
139+
dark={{ color: 'rgb(243,244,246)' }}
140+
flexDirection="column"
141+
>
142+
Like a Rolling Stone
143+
</Text>
144+
<PlayIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
117145
</Container>
118-
<Slider />
119146
<Container display="flex" alignItems="center" justifyContent="space-between">
120-
<Button size="icon" variant="ghost">
121-
<ArrowLeftIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
122-
</Button>
123-
<Button onClick={() => setCounter((c) => c + 1)} size="icon" variant="ghost" padding={8}>
124-
<PlayIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
125-
</Button>
126-
<Button size="icon" variant="ghost">
127-
<ArrowRightIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
128-
</Button>
147+
<Text
148+
fontSize={14}
149+
lineHeight={20}
150+
color="rgb(17,24,39)"
151+
dark={{ color: 'rgb(243,244,246)' }}
152+
flexDirection="column"
153+
>
154+
The Times They Are a-Changin'
155+
</Text>
156+
<PlayIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
129157
</Container>
130-
</Container>
131-
<Container padding={16} flexDirection="column">
132-
<Text
133-
fontSize={18}
134-
fontWeight={500}
135-
lineHeight={28}
136-
color="rgb(17,24,39)"
137-
dark={{ color: 'rgb(243,244,246)' }}
138-
marginBottom={8}
139-
flexDirection="column"
140-
>
141-
Playlist
142-
</Text>
143-
<Container flexDirection="column" gapRow={8}>
144-
<Container display="flex" alignItems="center" justifyContent="space-between">
145-
<Text
146-
fontSize={14}
147-
lineHeight={20}
148-
color="rgb(17,24,39)"
149-
dark={{ color: 'rgb(243,244,246)' }}
150-
flexDirection="column"
151-
>
152-
Like a Rolling Stone
153-
</Text>
154-
<PlayIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
155-
</Container>
156-
<Container display="flex" alignItems="center" justifyContent="space-between">
157-
<Text
158-
fontSize={14}
159-
lineHeight={20}
160-
color="rgb(17,24,39)"
161-
dark={{ color: 'rgb(243,244,246)' }}
162-
flexDirection="column"
163-
>
164-
The Times They Are a-Changin'
165-
</Text>
166-
<PlayIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
167-
</Container>
168-
<Container display="flex" alignItems="center" justifyContent="space-between">
169-
<Text
170-
fontSize={14}
171-
lineHeight={20}
172-
color="rgb(17,24,39)"
173-
dark={{ color: 'rgb(243,244,246)' }}
174-
flexDirection="column"
175-
>
176-
Subterranean Homesick Blues
177-
</Text>
178-
<PlayIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
179-
</Container>
158+
<Container display="flex" alignItems="center" justifyContent="space-between">
159+
<Text
160+
fontSize={14}
161+
lineHeight={20}
162+
color="rgb(17,24,39)"
163+
dark={{ color: 'rgb(243,244,246)' }}
164+
flexDirection="column"
165+
>
166+
Subterranean Homesick Blues
167+
</Text>
168+
<PlayIcon color="rgb(17,24,39)" dark={{ color: 'rgb(243,244,246)' }} />
180169
</Container>
181170
</Container>
182171
</Container>
183-
</Fullscreen>
184-
</XRLayer>
172+
</Root>
173+
</group>
185174
</XR>
186175
</Canvas>
187176
</>

examples/uikit/package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
"dependencies": {
33
"@pmndrs/pointer-events": "workspace:^",
44
"@react-three/drei": "^9.108.3",
5-
"@react-three/uikit": "^0.4.0",
6-
"@react-three/uikit-default": "^0.4.0",
7-
"@react-three/uikit-lucide": "^0.4.0",
5+
"@react-three/uikit": "^0.5.3",
6+
"@react-three/uikit-default": "^0.5.3",
7+
"@react-three/uikit-lucide": "^0.5.3",
88
"@react-three/xr": "workspace:^",
99
"leva": "^0.9.35"
1010
},

packages/pointer-events/src/intersections/ray.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,11 @@ export class CameraRayIntersector extends Intersector {
141141
}
142142

143143
computeIntersectionWorldPlane(this.viewPlane, intersection, object)
144-
const pointOnFace = this.raycaster.ray.intersectPlane(this.viewPlane, new Vector3()) ?? point
145144
return {
146145
...intersection,
147146
object,
148147
point,
149-
pointOnFace,
148+
pointOnFace: point,
150149
pointerPosition: this.fromPosition.clone(),
151150
pointerQuaternion: this.fromQuaternion.clone(),
152151
}

packages/pointer-events/src/intersections/utils.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ import { Plane, Intersection as ThreeIntersection, Object3D } from 'three'
22
import { Intersection, IntersectionOptions } from './index.js'
33
import { AllowedPointerEventsType, Pointer, type AllowedPointerEvents } from '../pointer.js'
44
import { hasObjectListeners } from '../utils.js'
5-
import { CombinedPointer } from '../index.js'
65

76
export function computeIntersectionWorldPlane(target: Plane, intersection: Intersection, object: Object3D): boolean {
8-
if (intersection.face == null) {
7+
const normal = intersection.normal ?? intersection.face?.normal
8+
if (normal == null) {
99
return false
1010
}
11-
target.setFromNormalAndCoplanarPoint(intersection.face.normal, intersection.localPoint)
11+
target.setFromNormalAndCoplanarPoint(normal, intersection.localPoint)
1212
target.applyMatrix4(object.matrixWorld)
1313
return true
1414
}

pnpm-lock.yaml

+23-10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)