<!DOCTYPE html> <html> <head> <title>Comp 86 example: Load external object</title> <script type="importmap"> { "imports": { "three": "https://unpkg.com/three@0.156.0/build/three.module.js", "three/addons/": "https://unpkg.com/three@0.156.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", 1 * 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", 0.5 * 2*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.05 * 2*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>