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
@@ -95,6 +95,24 @@ export const GetVelocity: NodeDef = {
|
||||
},
|
||||
};
|
||||
|
||||
export const JointPosition: NodeDef = {
|
||||
type: 'JointPosition',
|
||||
label: 'Joint position',
|
||||
category: 'data',
|
||||
description:
|
||||
'Where a hinge or a slider stands while the game is played: how far it has turned (degrees, ' +
|
||||
'a wheel counts on past a full round) or glided (world units) from how it was placed, and how fast ' +
|
||||
'that changes. 0 for a spring, a rope, a fixed joint, a joint that holds nothing, and in the editor run.',
|
||||
inputs: [obj('joint')],
|
||||
outputs: [num('value'), num('speed')],
|
||||
params: [],
|
||||
run: (ctx, inputs) => {
|
||||
const joint = asEntity(inputs.joint);
|
||||
const state = (joint && ctx.physics?.jointStateOf(joint)) || { value: 0, speed: 0 };
|
||||
return { outputs: { value: state.value, speed: state.speed } };
|
||||
},
|
||||
};
|
||||
|
||||
export const SetGravity: NodeDef = {
|
||||
type: 'SetGravity',
|
||||
label: 'Set gravity',
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
ApplyForce,
|
||||
ApplyImpulse,
|
||||
GetVelocity,
|
||||
JointPosition,
|
||||
SetAngularVelocity,
|
||||
SetGravity,
|
||||
SetVelocity,
|
||||
@@ -277,6 +278,7 @@ export const BUILT_IN_NODES: readonly NodeDef[] = [
|
||||
Spawn,
|
||||
Destroy,
|
||||
AddJoint,
|
||||
JointPosition,
|
||||
Emit,
|
||||
PlayAnimation,
|
||||
PauseAnimation,
|
||||
|
||||
Reference in new issue
Block a user