QuaternionHelper

by Matt

HTML

<base href="https://rawcdn.githack.com/mrdoob/three.js/r156/examples/" />
<script async src="https://cdn.jsdelivr.net/npm/[email protected]/dist/es-module-shims.js"></script>
<script type="importmap">
	{
		"imports": {
			"three": "https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js",
			"three/addons/": "https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/",
			"lil-gui": "https://cdn.jsdelivr.net/npm/[email protected]/dist/lil-gui.esm.min.js"
		}
	}
</script>

<template id="vertex-shader">
void main() {
	gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
</template>

<template id="fragment-shader">
uniform vec3 color;

void main() {
	gl_FragColor = vec4(color, 1.0);
}
</template>

CSS

canvas {
	position: fixed;
	inset: 0;
}

JavaScript

import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import { TransformControls } from 'three/addons/controls/TransformControls.js';
import { GUI } from 'lil-gui'

let scene, camera, renderer
let mesh, orbitControls, transformControls, clock
let params, attachOptions


const vec3 = new THREE.Vector3()
const vec4 = new THREE.Vector4()
const quat = new THREE.Quaternion()

class QuaternionHelper extends THREE.Object3D {

	constructor( object, axis = new THREE.Vector3(0, 0, 1) ) {
  
	  super()
  	
		const geometry = new THREE.BufferGeometry();

		const vertices = [];
		const colors = [];

		const color1 = new THREE.Color( 1, 0, 0 );  // original (red)
		const color2 = new THREE.Color( 0, 1, 0 );  // rotated (green)
    
    // original
    
    vertices.push(0, 0, 0)
    vertices.push(0, 0, 0)
    
    colors.push( color1.r, color1.g, color1.b );
    colors.push( color1.r, color1.g, color1.b );
    
    
    // rotated
    
		vertices.push(0, 0, 0)
    vertices.push(0, 0, 0)
    
    colors.push( color2.r, color2.g, color2.b );
    colors.push( color2.r, color2.g, color2.b );
    

		geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
		geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );

		const material = new THREE.LineBasicMaterial( { vertexColors: true, depthTest: false, depthWrite: false, toneMapped: false, transparent: true } );

		
    const line = new THREE.LineSegments(geometry, material)
    this.add(line)
    
    const materialArc = new THREE.MeshBasicMaterial({
    	depthTest: false,
      depthWrite: false,
      color: "green",
      opacity: 0.2,
      transparent: true,
      side: THREE.DoubleSide
    })
    
    // start from 12 o'clock, grows counterclockwise
    // arc plane (normal) faces +Z
    const geometryArc = new THREE.CircleGeometry(1, 32, Math.PI/2, 0)
    const arc = new THREE.Mesh(geometryArc, materialArc)
    //...