CylinderLink

DragControls

HTML

<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://threejs.org/examples/js/controls/DragControls.js"></script>

CSS

body {
  overflow: hidden;
  margin: 0;
  padding: 0;
}

JavaScript

var camera, scene, renderer, light;
var cube1, cube2;
var link;

init();
animate();

function init() {
const VERTEX_PARAMS = `
uniform float scaleZ;
uniform vec3 midPoint;
uniform vec4 rotation;`;

const VERTEX_POSITION = `
//vec3 scale = vec3( 1, 1, scaleZ );
//transformed = rotateVector(rotation, position * scale ) + midPoint;

vec3 src = vec3(0,1,1);
vec3 dest = vec3(3,1,1);

mat3 lookAt = calcLookAtMatrix(dest, src, vec3(0, 1, 0));
vec4 qua = q_look_at(lookAt);
vec3 scaled = vec3(1, 1, distance(src, dest));
vec3 midPoint = (src + dest) * 0.5;
transformed = rotateVector(qua, position * scaled) + midPoint;
`;

const VERTEX_FUNCTIONS = `
#define QUATERNION_IDENTITY vec4(0, 0, 0, 1)

vec4 q_look_at(mat3 m) {
    float m11 = m[0].x, m12 = m[1].x, m13 = m[2].x;
    float m21 = m[0].y, m22 = m[1].y, m23 = m[2].y;
    float m31 = m[0].z, m32 = m[1].z, m33 = m[2].z;

    float trace = m11 + m22 + m33;

    vec4 q = QUATERNION_IDENTITY;
    if (trace > 0.0) {
        float s = 0.5 / sqrt( trace + 1.0 );
        q.w = 0.25 / s;
        q.x = ( m32 - m23 ) * s;
        q.y = ( m13 - m31 ) * s;
        q.z = ( m21 - m12 ) * s;
        return q;
    }

    if ((m11 > m22) && (m11 > m33)) {
        float s = 2.0 * sqrt( 1.0 + m11 - m22 - m33 );
        q.w = ( m32 - m23 ) / s;
        q.x = 0.25 * s;
        q.y = ( m12 + m21 ) / s;
        q.z = ( m13 + m31 ) / s;
        return q;
    }

    if (m22 > m33) {
        float s = 2.0 * sqrt( 1.0 + m22 - m11 - m33 );
        q.w = ( m13 - m31 ) / s;
        q.x = ( m12 + m21 ) / s;
        q.y = 0.25 * s;
        q.z = ( m23 + m32 ) / s;
    }

    float s = 2.0 * sqrt(1.0 + m33 - m11 - m22);
    q.w = (m21 - m12) / s;
    q.x = (m13 + m31) / s;
    q.y = (m23 + m32) / s;
    q.z = 0.5 * s;
    return q;
}

// https://github.com/mrdoob/three.js/blob/master/src/math/Matrix4.js#L318
mat3 calcLookAtMatrix(vec3 eye, vec3 target, vec3 up) {
    vec3 z = normalize(eye - target);
    if (length(z) == 0.0) {
        // eye and target...