Skip to content

Instantly share code, notes, and snippets.

@twolfson
Last active July 29, 2021 17:43
Show Gist options
  • Save twolfson/cdf7445292a100425670948a6fa8a18d to your computer and use it in GitHub Desktop.
Save twolfson/cdf7445292a100425670948a6fa8a18d to your computer and use it in GitHub Desktop.
Three.js exploration playground

gist-threejs-playground

Playground environment for Three.js

Getting started

To get the repository running locally, run the following:

# Clone our repository
git clone <repo_url> gist-threejs-playground
cd gist-threejs-playground

# Pull our dependencies
./bootstrap.sh

# Start our web server
python3 -m http.server --bind 127.0.0.1
# Serving HTTP on 127.0.0.1 port 8000 ...

We can now visit our index.html at http://localhost:8000/

#!/usr/bin/env bash
# Exit on first error, unset variable, or pipe failure
set -euo pipefail
# Move to our vendor folder
mkdir -p vendor
cd vendor
# Pull our dependencies
wget --timestamping http://threejs.org/build/three.js
wget --timestamping https://cdn.rawgit.com/mrdoob/three.js/r87/examples/js/controls/OrbitControls.js
wget --timestamping https://cdn.rawgit.com/toji/gl-matrix/v2.4.0/dist/gl-matrix.js
body {
margin: 0;
}
canvas {
width: 100%;
height: 100%;
}
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<title>gist-threejs-playground</title>
<link rel="stylesheet" href="index.css" />
</head>
<body>
<script src="vendor/three.js"></script>
<script src="vendor/OrbitControls.js"></script>
<script src="vendor/gl-matrix.js"></script>
<script src="index.js"></script>
</body>
</html>
// Localize our variables
var Vector3 = THREE.Vector3;
var vec3 = window.vec3; /* via glMatrix */
// Define helper methods
Vector3.fromArray = function (arr) {
return new Vector3(arr[0], arr[1], arr[2]);
};
// Define our scene and perspective camera
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 500);
camera.position.set(0, 10, 10);
camera.lookAt(new THREE.Vector3(0, 0, 0));
// Define our renderer
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
// Append our rendered result to the DOM
document.body.appendChild(renderer.domElement);
// Bind orbit controls to our scene
// https://github.com/mrdoob/three.js/blob/r87/examples/webgl_animation_cloth.html#L284-L288
var controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.maxPolarAngle = Math.PI * 0.5;
controls.minDistance = 10;
controls.maxDistance = 1000;
// Define a vector drawing helper
function drawVector(startVertex, endVertex, color) {
color = color || 0xCCCCCC;
var lineMaterial = new THREE.LineBasicMaterial({
color: color
});
var lineGeometry = new THREE.Geometry();
lineGeometry.vertices.push(startVertex);
lineGeometry.vertices.push(endVertex);
var line = new THREE.Line(lineGeometry, lineMaterial);
scene.add(line);
return line;
}
// Define our problem set we're dealing with
// Define our axis and an offshoot vector where we want to remove the axis component
var axisVector = vec3.fromValues(0, 3, 0);
var offshootVector = vec3.fromValues(1, 1, 0);
// Isolate and vectorize the projection of our offshoot onto the axis
// dot = |axis||offshoot|cos(theta)
// projectionScalar = |offshoot|cos(theta)
// projectionVector = axisUnitVector * |offshoot|cos(theta)
var axisOffshootDot = vec3.dot(axisVector, offshootVector);
var axisVectorLength = vec3.length(axisVector);
var projectionScalar = axisOffshootDot / axisVectorLength;
var axisUnitVector = vec3.clone(axisVector);
vec3.normalize(axisUnitVector, axisUnitVector);
var projectionVector = vec3.clone(axisUnitVector);
vec3.scale(projectionVector, projectionVector, projectionScalar);
// Calculate the resulting vector via vector addition
var orthoVector = vec3.create();
vec3.sub(orthoVector, offshootVector, projectionVector);
// Draw our results
drawVector(new Vector3(0, 0, 0), Vector3.fromArray(axisVector), 0XFF0000);
drawVector(new Vector3(0, 0, 0), Vector3.fromArray(offshootVector), 0x00FF00);
drawVector(new Vector3(0, 0, 0), Vector3.fromArray(projectionVector), 0xFFFF00);
drawVector(new Vector3(0, 0, 0), Vector3.fromArray(orthoVector), 0x0000FF);
// Add a grid
var gridHelper = new THREE.GridHelper(
200 /* Size , 20 /* Subdivisions */, 0x0000FF /* Center line color */, 0x8080FF /* Non-center lines color */);
gridHelper.position.x = 0;
gridHelper.position.y = -1;
gridHelper.position.z = 0;
scene.add(gridHelper);
// Define our render and update loop
function animate() {
// Queue up render after our serial logic completes
requestAnimationFrame(animate);
// Run a render update
renderer.render(scene, camera);
}
// Start our render/update loop
animate();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment