From f77ff74f94166d0476d1668997e7daef6f03e085 Mon Sep 17 00:00:00 2001 From: Jake Date: Wed, 5 Nov 2025 15:26:02 +0800 Subject: [PATCH] fixed parenting of sample.urdf --- script.js | 131 +++++++++++--- urdf/sample.urdf | 445 +++++++++++++++++++++++++++-------------------- 2 files changed, 361 insertions(+), 215 deletions(-) diff --git a/script.js b/script.js index b2497b1..c8fff56 100644 --- a/script.js +++ b/script.js @@ -80,6 +80,65 @@ function createRotationArc(axis, lower, upper, radius = 0.1, segments = 32) { return new THREE.Line(geometry, material); } +function createRotationSector(axis, lower, upper, radius = 0.1, segments = 64) { + const shape = new THREE.Shape(); + shape.moveTo(0, 0); + + for (let i = 0; i <= segments; i++) { + const angle = lower + (upper - lower) * (i / segments); + shape.lineTo(Math.cos(angle) * radius, Math.sin(angle) * radius); + } + + shape.lineTo(0, 0); // close the shape + + const geometry = new THREE.ShapeGeometry(shape); + const material = new THREE.MeshBasicMaterial({ + color: 0x888888, // light gray + transparent: true, + opacity: 0.3, // translucent + side: THREE.DoubleSide, // show both sides of the fill + depthTest: false, // ✅ always on top + depthWrite: false + }); + + + const mesh = new THREE.Mesh(geometry, material); + + // Orient the sector to match the axis + const basis = new THREE.Matrix4(); + const up = new THREE.Vector3(0, 0, 1); + const quaternion = new THREE.Quaternion().setFromUnitVectors(up, axis.clone().normalize()); + basis.makeRotationFromQuaternion(quaternion); + mesh.applyMatrix4(basis); + + return mesh; +} + +function createAngleIndicator(axis, angle, radius = 0.1) { + const dir = new THREE.Vector3(Math.cos(angle), Math.sin(angle), 0).multiplyScalar(radius); + + const geometry = new THREE.BufferGeometry().setFromPoints([ + new THREE.Vector3(0, 0, 0), + dir, + ]); + + const material = new THREE.LineBasicMaterial({ + color: 0xffffff, // white + linewidth: 2, // note: linewidth only works in some renderers + depthTest: false, // ✅ always on top + depthWrite: false +}); + + const line = new THREE.Line(geometry, material); + + // Rotate into axis plane + const up = new THREE.Vector3(0, 0, 1); + const quaternion = new THREE.Quaternion().setFromUnitVectors(up, axis.clone().normalize()); + line.applyQuaternion(quaternion); + + return line; +} + // Load URDF @@ -117,26 +176,39 @@ loader.load('./urdf/sample.urdf', robot => { const intersects = raycaster.intersectObjects(robot.children, true); if (isDragging && draggedJoint && worldAxis) { - const deltaX = event.clientX - lastX; - lastX = event.clientX; - const angleDelta = deltaX * 0.005; + const deltaX = event.clientX - lastX; + lastX = event.clientX; + const angleDelta = deltaX * 0.005; - const jointName = draggedJoint.name; - const limits = robot.joints[jointName]?.limit; - const lower = limits?.lower ?? -Math.PI; - const upper = limits?.upper ?? Math.PI; + const jointName = draggedJoint.name; + const limits = robot.joints[jointName]?.limit; + const lower = limits?.lower ?? -Math.PI; + const upper = limits?.upper ?? Math.PI; - const currentAngle = jointAngles[jointName] ?? 0; - const proposedAngle = currentAngle + angleDelta; + const currentAngle = jointAngles[jointName] ?? 0; + const proposedAngle = currentAngle + angleDelta; - // ✅ Clamp to limits - const clampedAngle = Math.max(lower, Math.min(upper, proposedAngle)); - const actualDelta = clampedAngle - currentAngle; + // ✅ Clamp to limits + const clampedAngle = Math.max(lower, Math.min(upper, proposedAngle)); + const actualDelta = clampedAngle - currentAngle; - // ✅ Apply rotation - draggedJoint.rotateOnAxis(worldAxis, actualDelta); - jointAngles[jointName] = clampedAngle; -} + // ✅ Apply rotation + draggedJoint.rotateOnAxis(worldAxis, actualDelta); + jointAngles[jointName] = clampedAngle; + + + // Remove old indicator + if (draggedJoint.userData.gizmo?.indicator) { + draggedJoint.parent.remove(draggedJoint.userData.gizmo.indicator); + } + + // Add updated indicator + const newIndicator = createAngleIndicator(worldAxis, jointAngles[jointName]); + newIndicator.position.copy(draggedJoint.position); + draggedJoint.parent.add(newIndicator); + draggedJoint.userData.gizmo.indicator = newIndicator; + + } @@ -206,14 +278,22 @@ loader.load('./urdf/sample.urdf', robot => { } worldAxis = urdfAxis.normalize(); - const limits = draggedJoint?.limit; - console.log(limits); + const limits = robot.joints[jointName]?.limit; const lower = limits?.lower ?? -Math.PI; const upper = limits?.upper ?? Math.PI; - arc = createRotationArc(worldAxis, lower, upper); - draggedJoint.parent.add(arc); - arc.position.copy(draggedJoint.position); - jointAngles[jointName] ??= 0; + + const sector = createRotationSector(worldAxis, lower, upper); + const indicator = createAngleIndicator(worldAxis, jointAngles[jointName] ?? 0); + + sector.position.copy(draggedJoint.position); + indicator.position.copy(draggedJoint.position); + + draggedJoint.parent.add(sector); + draggedJoint.parent.add(indicator); + + // Store for cleanup + draggedJoint.userData.gizmo = { sector, indicator }; + @@ -228,7 +308,12 @@ loader.load('./urdf/sample.urdf', robot => { canvas.addEventListener('pointerup', () => { isDragging = false; controls.enabled = true; - draggedJoint.parent.remove(arc); + const gizmo = draggedJoint?.userData.gizmo; + if (gizmo) { + draggedJoint.parent.remove(gizmo.sector); + draggedJoint.parent.remove(gizmo.indicator); + } + draggedJoint = null; worldAxis = null; diff --git a/urdf/sample.urdf b/urdf/sample.urdf index e6b5cd0..296d6a4 100644 --- a/urdf/sample.urdf +++ b/urdf/sample.urdf @@ -4,6 +4,7 @@ + @@ -28,11 +29,12 @@ - - - - - + + + + + + @@ -55,12 +57,13 @@ - - - - - - + + + + + + + @@ -83,12 +86,13 @@ - - - - - - + + + + + + + @@ -111,12 +115,13 @@ - - - - - - + + + + + + + @@ -141,258 +146,311 @@ - - - - - + + + + + + - - + + + + - + - - + + + + - - - + + + + - - - - - + + + + + + - - + + + + - + - - + + + + - - - + + + + - - - - - + + + + + + - - + + + + - + - - + + + + - - - + + + + - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + - - + + + + - + - - + + + + - - - + + + + - - - - - + + + + + + - - + + + + - + - - + + + + - - - + + + + - - - - - + + + + + - + + - - - - + + + + + + - - + + + + - - - + + + - - - - - - + + + + + + + + + + @@ -415,12 +473,15 @@ - - - - - - + + + + + + + + +