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

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more