I'm building a Wacom tablet-driven cloth editing rig in visionOS: a persistent grab sphere
(one Entity with ClothGrabComponent, volume mode) parented to the simulation root,
toggled with isGrabbing on each pen-down. A single grab behaves correctly — the cloth
follows the sphere, nothing else moves.
On the second grab at a different position (same cloth, no rebuild), the component
keeps dragging the particles from the FIRST grab to the new sphere position — its
internal grab coordinates are not updated by the new activation. The vertex that was
just bound is pushed away from the sphere at the same time.
Instrumented demo is (0.5 × 0.5 m grid, 289 vertices, four corners pinned, gravity = 0,
sphere radius 0.06, falloff = .disabled), grab A at vertex #294 (−0.118, +0.118),
release, then grab B at vertex #105 (+0.118, −0.118) — 0.335 m apart:
t = 345.9 GRAB_B starts: previous #294 disp = 0.000 dist-to-ball = 0.335
current #105 disp = 0.000 dist-to-ball = 0.000
t = 346.4 (+0.5 s): previous #294 disp = 0.335 dist-to-ball = 0.000 ← dragged to the NEW ball
current #105 disp = 0.191 dist-to-ball = 0.191 ← pushed AWAY from the ball
t = 347.0 … 349.6 previous #294 pinned at ball (dist 0.000), #105 held away at 0.16–0.19
t = 351.9 after release: #294 back to rest (0.012), cloth flat again
The 0.335 m displacement of #294 happens within half a second and equals exactly the
distance from #294's rest position to the new sphere — the previous grab's particle
set is being pulled toward the new sphere location, as if the component re-applied the
old grab selection with the new transform. this can repeat with
identical numbers.
The docs for isGrabbing only say "Indicates whether particles are
currently being grabbed" — they don't describe what happens on a false→true transition
after the entity has moved, which is the case the official sample never demonstrates.
The setup is the one shown in the official sample — a persistent entity carrying the
grab component, isGrabbing toggled per interaction:
// makeCloth — once
let dragBall = makeBall(radius: 0.015, parent: simRoot)
var grab = ClothGrabComponent(mode: .volume(shape: .sphere(ClothSphereShape(radius: 0.06))))
grab.falloff = .disabled
dragBall.components.set(grab)
// grab: move ball to new vertex, activate
dragBall.position = body.convert(position: vertexPos, to: simRoot)
var g = dragBall.components[ClothGrabComponent.self]!
g.isGrabbing = true
dragBall.components.set(g)
// release: deactivate only
var g = dragBall.components[ClothGrabComponent.self]!
g.isGrabbing = false
dragBall.components.set(g)
some tries:
Remove and re-add ClothGrabComponent on each grab — the simulator crashes within 1–2 frames with Assertion failed
Rebuild the whole ClothBodyComponent between grabs
Environment: Xcode 27 beta (build 24M5316i), xrOS 27.0 SDK, simulator runtime
com.apple.CoreSimulator.SimRuntime.xrOS-27-0 (avp1). All Cloth* APIs are Beta on
visionOS 27
0
0
27