Published
Edited
May 11, 2022
Insert cell
Insert cell
Insert cell
renderer.domElement
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// Continuously updates
{
while (true) {
// ray must be projected from the outside in
const topBounds = new THREE.Vector3(0, 2, 0);
const top = intersects(topBounds, originPoint);
yellowPoint.position.set(top.x, top.y, top.z);

const bottomBounds = new THREE.Vector3(0, -2, 0);
const bottom = intersects(bottomBounds, originPoint);
purplePoint.position.set(bottom.x, bottom.y, bottom.z);

const leftBounds = new THREE.Vector3(-2, 0, 0);
const left = intersects(leftBounds, originPoint);
fuchsiaPoint.position.set(left.x, left.y, left.z);

const rightBounds = new THREE.Vector3(2, 0, 0);
const right = intersects(rightBounds, originPoint);
olivePoint.position.set(right.x, right.y, right.z);

const frontBounds = new THREE.Vector3(0, 0, 2);
const front = intersects(frontBounds, originPoint);
orchidPoint.position.set(front.x, front.y, front.z);

const backBounds = new THREE.Vector3(0, 0, -2);
const back = intersects(backBounds, originPoint);
springPoint.position.set(back.x, back.y, back.z);

importedObj.rotation.z += 0.01;
renderer.render(scene, camera);
yield null;
}
}
Insert cell
Insert cell
{
// show position of raycast origin
magentaPoint.position.set(originPoint.x, originPoint.y, originPoint.z);
}
Insert cell
// raycaster code
function intersects(start = new THREE.Vector3(), end = new THREE.Vector3()) {
const raycaster = new THREE.Raycaster();
var dir = new THREE.Vector3();
raycaster.set(start, dir.subVectors(end, start).normalize());
// const intersects = raycaster.intersectObjects(scene.children, true); // works but checks for all scene objs
const intersects = raycaster.intersectObject(importedObj, true);

var id = 0;
if (intersects[id]) {
var x = intersects[id].point.x;
var y = intersects[id].point.y;
var z = intersects[id].point.z;
return { x: x, y: y, z: z };
} else {
return { x: 0, y: 0, z: 0 };
}
}
Insert cell
function pointHelper(color = "green") {
const geometry = new THREE.BoxGeometry(0.1, 0.1, 0.1);
const material = new THREE.MeshBasicMaterial({ color: color });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
return mesh;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
importedObj = {
const url = await FileAttachment("tubo.obj").url()
return loadObject(url)
}
Insert cell
Insert cell
{
const material = new THREE.MeshNormalMaterial( { transparent: true, opacity: 0.5 } );
// add material to imported object
importedObj.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.material = material;
}
});
importedObj.position.set = (0, 0, 0);
const s = 0.1;
importedObj.scale.set(s, s, s);
scene.add(importedObj);
}
Insert cell
Insert cell
loadObject = (url) => new Promise ((resolve,reject) => {
const loader = new THREE.OBJLoader();
// instantiate a loader
loader.load(
// resource URL
url,
// called when resource is loaded
function ( object ) {
resolve(object);
},
// called when loading is in progresses
function ( xhr ) {
return ( xhr.loaded / xhr.total * 100 ) + '% loaded' ;
},
// called when loading has errors
function ( error ) {
reject ("Error in loading")
}
);
})
Insert cell
Insert cell
scene = {
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x001b42);
return scene;
}
Insert cell
camera = {
const fov = 45;
const aspect = width / height;
const near = 1;
const far = 1000;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(2, 2, -2)
camera.lookAt(new THREE.Vector3(0, 0, 0));
return camera;
}
Insert cell
renderer = {
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(width, height);
renderer.setPixelRatio(devicePixelRatio);
//renderer.domElement.addEventListener("mousemove", onMouseMove);
const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.addEventListener("change", () => renderer.render(scene, camera));
invalidation.then(() => (controls.dispose(), renderer.dispose()));
return renderer;
}
Insert cell
height = 600
Insert cell
THREE = {
const THREE = window.THREE = await require("three@0.130.0/build/three.min.js");
await require("three@0.130.0/examples/js/controls/OrbitControls.js").catch(() => {});
await require("three@0.130.0/examples/js/loaders/OBJLoader.js").catch(() => {});
return THREE;
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more