Let a joint glide on a rail and drive it with a motor (#154)
Step 2 of the joints: a door that opens by itself, a lift and a piston need a joint that slides along one line and a motor that turns or pushes. A graph also needs to read how far such a joint stands. - Slider: a fifth joint type on Rapier's prismatic joint. Its rail is the joint's own x axis, so turning the joint turns the rail. Joints now carry Scale, Rotation and Mirror like a sprite. - Limit distance with Min and Max, in world units from where the object was placed. - Motor on hinge and slider: Off, Speed or Target, with Motor speed, Motor target and Max force (0 = no limit). Target goes there at no more than the speed and slows down for the last stretch. - Changing speed, target or force keeps the engine joint. Switching the motor on or off builds it again. - New node Joint position: value and speed of a hinge (degrees, counting past a full round) or a slider (world units). - Scene view draws a slider's rail dashed, with a tick at each limit. - shownFor in the schema takes a list of choices that must all hold. Findings, measured with a probe against Rapier 0.20: - A prismatic joint holds both bodies at one angle. Held to the scene or to an object without a rigidbody, the joint's own anchor body is turned by the placed difference, so nothing jumps. Between two rigidbodies the held one is turned to match, and the console says so once. - Rapier reads no joint angle back. The position is worked out from the two bodies. - A hinge motor is weak on a small body at the end of a long arm (box 20 on an arm of 100 does not lift itself). More solver iterations would help but cost every scene. A door of 100 x 20 reaches -90 and holds it. This is written in the wiki. Tests: - Unit: 16 new in joints.test.ts, 1 in joint-links, 3 catalog cases. - e2e 41: 27 checks (25 + 2), block 41f with a real mouse in the inspector and the motor in play (59.1 of 60 units in 1 s). - 9 of 9 unit counter-probes fail as they should. - Gate: 220 files, 3436 tests (3416 + 20), CHECK EXIT 0. - e2e total 1701 is counted (1699 + 2), the full suite did not run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4716726b6b
commit
f1e3bd8378
16 files changed
+738
-34
No files matched your search
@@ -135,6 +135,7 @@ const physicsDouble = (): PhysicsDouble => {
|
||||
),
|
||||
applyImpulse: (target, x, y) => (calls.push(['applyImpulse', target.id, x, y]), has(target)),
|
||||
setGravity: (x, y) => void calls.push(['setGravity', x, y]),
|
||||
jointStateOf: (target) => (target.id === 'hinge' ? { value: 30, speed: -12 } : null),
|
||||
};
|
||||
};
|
||||
const physicsCalls = (ctx: FakeContext) => (ctx.physics as PhysicsDouble).calls;
|
||||
@@ -1462,6 +1463,25 @@ const CASES: Record<string, Case[]> = {
|
||||
},
|
||||
{ name: 'without physics it reads 0', inputs: { object: crate }, outputs: { x: 0, y: 0, angular: 0 } },
|
||||
],
|
||||
JointPosition: [
|
||||
{
|
||||
name: 'reads how far the joint stands from where it was placed, and how fast',
|
||||
inputs: { joint: fakeEntity('hinge') },
|
||||
context: { physics: physicsDouble() },
|
||||
outputs: { value: 30, speed: -12 },
|
||||
},
|
||||
{
|
||||
name: 'a joint the engine does not read reads 0',
|
||||
inputs: { joint: fakeEntity('rope') },
|
||||
context: { physics: physicsDouble() },
|
||||
outputs: { value: 0, speed: 0 },
|
||||
},
|
||||
{
|
||||
name: 'without physics it reads 0',
|
||||
inputs: { joint: fakeEntity('hinge') },
|
||||
outputs: { value: 0, speed: 0 },
|
||||
},
|
||||
],
|
||||
SetGravity: [
|
||||
{
|
||||
name: 'sets the scene gravity',
|
||||
|
||||
Reference in new issue
Block a user