three.js connecting two moving objects with 3d 'rope'

664 Views Asked by At

I am trying to create an industrial robot model with moving parts (movement controlled with dat.gui panel).

screenshot of the model

Issue: I cant figure out how to make the rope part (number 3 in the image) which would adjust it's length when the 'hook' part (number 2) is being moved up and down. The rope should stay connected to the hook and base (number 1) at all times.

I initially tried using tube geometry, but couldn't figure out how to correctly manipulate it to get the desired result.

you can find source code here: https://gitlab.com/enrika/three.js-studies/blob/cfabd98a08b84566a6de2839328d3bd7c95442a8/robot

Perhaps there is a specific shape that would be easier to work with? Any feedback and tips are appreciated!

1

There are 1 best solutions below

1
On BEST ANSWER

If I got you correctly, then you can use scaling of the rope's mesh:

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(5, 10, 10);
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var base = new THREE.Mesh(new THREE.BoxGeometry(3, 1, 3), new THREE.MeshBasicMaterial({
  color: "red",
  wireframe: true
}));
base.position.setY(5);
scene.add(base);

var hook = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), new THREE.MeshBasicMaterial({
  color: "green",
  wireframe: true
}));
hook.position.set(0, -5, 0);
base.add(hook);

var rope = new THREE.Mesh(new THREE.BoxGeometry(0.1, 1, 0.1), new THREE.MeshBasicMaterial({
  color: "blue"
}));
rope.geometry.translate(0, -0.5, 0);
rope.scale.y = Math.abs(hook.position.y);
base.add(rope);

var gui = new dat.GUI();
gui.add(hook.position, "y", -5, -1).onChange(v => {
  rope.scale.y = Math.abs(v) // scale the rope along Y-axis
});

render();

function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}
body {
  overflow: hidden;
  margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/98/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.3/dat.gui.min.js"></script>