<!DOCTYPE html>
<html>
<head>
<title>CS 86 example: Load external object</title>
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@0.181.0/build/three.module.js",
"three/addons/": "https://unpkg.com/three@0.181.0/examples/jsm/"
}
}
</script>
<script type="module">
class SceneGraph extends THREE.Scene {
constructor () {
super()
let loader = new OBJLoader () //*1 Load it, get callback when loaded
// NB downloaded from http://artist-3d.com/free_3d_models/dnm/model_disp.php?uid=4587
loader.load ("Beethoven.obj", //*1
(obj) => { //*1
// Move it to where we want it
obj.position.set (0, -5, -10) //*2 Move it and add to scene
this.add (obj); //*2
})
}
}
/*
* An object to hold the lights, same as previous
*/
class Lights {
constructor (scene) {
// Uses typical lighting setup, like portrait or TV studio...
// Main (key) light, directional,
// from 45 deg. user's right, above, bright white
this.mainLight = new THREE.DirectionalLight ("white", 2 * Math.PI)
this.mainLight.position.set (1, 0.5, 1)
scene.add (this.mainLight)
// Fill light, directional, from 45deg. user's left,
// white, half as bright
this.fillLight = new THREE.DirectionalLight ("white", 1 * Math.PI)
this.fillLight.position.set (-1, 0, 1 )
scene.add (this.fillLight)
// Ambient light, white, still less bright
this.ambientLight = new THREE.AmbientLight ("white", 0.1 * Math.PI)
scene.add (this.ambientLight);
}
}
/*
* The rest of this is the same boilerplate as previously,
* except for the additional import
*/
import * as THREE from "three";
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { OBJLoader } from 'three/addons/loaders/OBJLoader.js'; //*1
class Main {
constructor () {
// Set up window for 3D
this.renderer = new THREE.WebGLRenderer( { antialias: true } );
this.renderer.setClearColor( new THREE.Color ("lightgrey"))
this.renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( this.renderer.domElement );
// Create our scene
this.scene = new SceneGraph();
// Add our lights to the scene, we keep in a separate class
new Lights(this.scene);
// Create the camera
this.camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
this.camera.position.z = 5;
// Create a camera contol
new OrbitControls( this.camera, this.renderer.domElement );
// Start animation loop
this.animate()
// In case window is resized
// use () form of function definition cause need "this"
// but don't need "event" arg
window.onresize = () => this.onResize()
}
/*
* Render the scene
*/
render() {
this.renderer.render( this.scene, this.camera );
}
/*
* Animation loop
*/
animate () {
requestAnimationFrame (() => {this.animate()});
this.render()
}
// In case window is resized
onResize () {
this.renderer.setSize( window.innerWidth, window.innerHeight );
this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix();
this.render()
}
}
window.onload = () => new Main ()
</script>
</head>
</html>