TA159

Notas, resueltos y trabajos practicos de la materia Sistemas Gráficos
Index Commits Files Refs Submodules README LICENSE
tp/src/standalone/train.js (10880B)
   1 import * as THREE from 'three';
   2 import * as dat from 'dat.gui';
   3 import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js';
   4 
   5 import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
   6 
   7 let scene, camera, renderer, container, terrainMaterial, instancedTrees;
   8 
   9 let time = 0.0;
  10 
  11 function onResize() {
  12     camera.aspect = container.offsetWidth / container.offsetHeight;
  13     camera.updateProjectionMatrix();
  14     renderer.setSize(container.offsetWidth, container.offsetHeight);
  15 }
  16 
  17 function setupThreeJs() {
  18     scene = new THREE.Scene();
  19     container = document.getElementById('mainContainer');
  20 
  21     renderer = new THREE.WebGLRenderer();
  22     renderer.setClearColor(0x606060);
  23     container.appendChild(renderer.domElement);
  24 
  25     camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 0.1, 1000);
  26     camera.position.set(-50, 60, 50);
  27     camera.lookAt(0, 0, 0);
  28 
  29     const controls = new OrbitControls(camera, renderer.domElement);
  30 
  31     const ambientLight = new THREE.AmbientLight(0xAAAAAA);
  32     scene.add(ambientLight);
  33 
  34     const hemisphereLight = new THREE.HemisphereLight(0xffffff, 0x000000, 0.25);
  35     scene.add(hemisphereLight);
  36 
  37     const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
  38     directionalLight.position.set(100, 100, 100);
  39     scene.add(directionalLight);
  40 
  41     const directionalLightHelper = new THREE.DirectionalLightHelper(directionalLight, 5);
  42     // scene.add(directionalLightHelper);
  43 
  44     const gridHelper = new THREE.GridHelper(50, 20);
  45     scene.add(gridHelper);
  46 
  47     const axesHelper = new THREE.AxesHelper(5);
  48     scene.add(axesHelper);
  49 
  50     window.addEventListener('resize', onResize);
  51     onResize();
  52 }
  53 
  54 const steamChamberLen = 10;
  55 const steamChamberRad = 2.50;
  56 const steamChamberEndRad = steamChamberRad+0.375;
  57 const steamChamberEndLen = 2.50;
  58 const cabinLen = 5;
  59 const cabinHeight = 6;
  60 const cabinRoofHeight = 3;
  61 const cabinWallThickness = 0.375;
  62 const wheelRad = 1.475;
  63 const chassisHeight = 2.5;
  64 const wheelThickness = 0.425;
  65 const chassisOffset = 1.245;
  66 const wheelOffset = -0.45;
  67 const steamCylindersLen = 4;
  68 const crankLen = 12;
  69 const crankOffset = 1.50;
  70 const crankWidth = 0.25;
  71 
  72 let crankLeft, crankRight;
  73 
  74 function buildCabinRoof() {
  75     console.log('Building train cabin roof');
  76     const geometry = new THREE.BoxGeometry(6, cabinWallThickness, 6);
  77     return geometry;
  78 }
  79 
  80 function buildCabin() {
  81     console.log('Building train cabin');
  82 
  83     let cabin = [];
  84 
  85     const cabinFront = new THREE.BoxGeometry(
  86         steamChamberRad*2,
  87         cabinWallThickness,
  88         cabinHeight);
  89 
  90     cabinFront.translate(0, cabinLen/2, -cabinHeight/2);
  91     cabin.push(cabinFront);
  92 
  93     const cabinLeft = new THREE.BoxGeometry(
  94         steamChamberRad*2,
  95         cabinWallThickness,
  96         cabinHeight);
  97 
  98     cabinLeft.rotateZ(Math.PI/2);
  99     cabinLeft.translate(
 100         steamChamberRad-cabinWallThickness/2,
 101         cabinWallThickness/2,
 102         -cabinHeight/2);
 103 
 104     cabin.push(cabinLeft);
 105 
 106     const cabinRight = new THREE.BoxGeometry(
 107         steamChamberRad*2,
 108         cabinWallThickness,
 109         cabinHeight);
 110 
 111     cabinRight.rotateZ(Math.PI/2);
 112     cabinRight.translate(
 113         -steamChamberRad+cabinWallThickness/2,
 114         cabinWallThickness/2,
 115         -cabinHeight/2);
 116 
 117     cabin.push(cabinRight);
 118 
 119     const g1 = new THREE.BoxGeometry(
 120         cabinWallThickness, cabinWallThickness, cabinRoofHeight);
 121 
 122     g1.rotateZ(Math.PI/2);
 123     g1.translate(
 124         -steamChamberRad+(cabinWallThickness/2),
 125         -steamChamberRad+cabinWallThickness,
 126         -cabinHeight-cabinRoofHeight/2);
 127 
 128     cabin.push(g1);
 129 
 130     const g2 = new THREE.BoxGeometry(
 131         cabinWallThickness, cabinWallThickness, cabinRoofHeight);
 132 
 133     g2.rotateZ(Math.PI/2);
 134     g2.translate(
 135         steamChamberRad-cabinWallThickness/2,
 136         steamChamberRad,
 137         -cabinHeight-cabinRoofHeight/2);
 138 
 139     cabin.push(g2);
 140 
 141     const g3 = new THREE.BoxGeometry(
 142         cabinWallThickness, cabinWallThickness, cabinRoofHeight);
 143 
 144     g3.rotateZ(Math.PI/2);
 145     g3.translate(
 146         steamChamberRad-cabinWallThickness/2,
 147         -steamChamberRad+cabinWallThickness,
 148         -cabinHeight-cabinRoofHeight/2);
 149 
 150     cabin.push(g3);
 151 
 152     const g4 = new THREE.BoxGeometry(
 153         cabinWallThickness, cabinWallThickness, cabinRoofHeight);
 154 
 155     g4.rotateZ(Math.PI/2);
 156     g4.translate(
 157         -steamChamberRad+cabinWallThickness/2,
 158         steamChamberRad,
 159         -cabinHeight-cabinRoofHeight/2);
 160 
 161     cabin.push(g4);
 162 
 163     const geometry = BufferGeometryUtils.mergeGeometries(cabin);
 164     geometry.rotateX(Math.PI/2);
 165     return geometry;
 166 }
 167 
 168 function buildChamber() {
 169     let geometries = [];
 170 
 171     const steamChamber = new THREE.CylinderGeometry(steamChamberRad,
 172         steamChamberRad, steamChamberLen, 32);
 173     
 174     geometries.push(steamChamber);
 175 
 176     const steamChamberEnd = new THREE.CylinderGeometry(steamChamberEndRad,
 177         steamChamberEndRad, steamChamberEndLen, 32);
 178 
 179     steamChamberEnd.translate(0,steamChamberLen/2 + steamChamberEndLen/2,0);
 180     geometries.push(steamChamberEnd);
 181 
 182     const floor = new THREE.BoxGeometry(
 183         steamChamberRad*2, steamChamberLen + steamChamberEndLen + cabinLen, 1.0);
 184     floor.translate(0, -steamChamberEndLen/2, steamChamberRad);
 185     geometries.push(floor);
 186 
 187     const chamberPipeLen = 4;
 188     const chamberPipe = new THREE.CylinderGeometry(0.55, 0.55, chamberPipeLen, 32);
 189     chamberPipe.translate(0, -(steamChamberRad + chamberPipeLen/2)+1.0,
 190         -(steamChamberLen+steamChamberEndLen)/2);
 191 
 192     chamberPipe.rotateX(Math.PI/2);
 193     geometries.push(chamberPipe);
 194 
 195     const geometry = BufferGeometryUtils.mergeGeometries(geometries);
 196     geometry.rotateX(Math.PI/2);
 197     geometry.translate(0, steamChamberRad+0.25, 0);
 198     return geometry;
 199 }
 200 
 201 function buildTrainWheel() {
 202     const wheel = new THREE.CylinderGeometry(wheelRad, wheelRad, wheelThickness);
 203     wheel.rotateZ(Math.PI/2);
 204 
 205     const wheelBolt = new THREE.CylinderGeometry(wheelRad, wheelRad, wheelThickness);
 206     wheelBolt.rotateZ(Math.PI/2);
 207 
 208     const wheelsMaterial = new THREE.MeshPhongMaterial({
 209         color: 0x393939, 
 210         side: THREE.DoubleSide,
 211         shininess: 100.0
 212     });
 213 
 214     return new THREE.Mesh(wheel, wheelsMaterial)
 215 }
 216 
 217 function buildTrainAxe(material) {
 218     const axeGeometry = new THREE.CylinderGeometry(0.325, 0.325, 5);
 219     axeGeometry.rotateZ(Math.PI/2);
 220 
 221     const axeMaterial = new THREE.MeshPhongMaterial({
 222         color: 0x7A7F80, 
 223         side: THREE.DoubleSide,
 224         shininess: 100.0
 225     });
 226 
 227     return new THREE.Mesh(axeGeometry, axeMaterial);
 228 }
 229 
 230 function buildTrainChassis() {
 231     const chassis = new THREE.BoxGeometry(3.5, 2.5, steamChamberLen+steamChamberEndLen+cabinLen);
 232     return chassis;
 233 }
 234 
 235 function buildTrain() {
 236     console.log('Building train');
 237     const train = new THREE.Group();
 238 
 239     const chassisGeometry = buildTrainChassis();
 240     const chassisMaterial = new THREE.MeshPhongMaterial({
 241         color: 0x7A7F80, 
 242         side: THREE.DoubleSide,
 243         shininess: 100.0
 244     });
 245 
 246     const chassis = new THREE.Mesh(chassisGeometry, chassisMaterial);
 247     train.add(chassis);
 248 
 249     const chamberGeometry = buildChamber();
 250     const chamberMaterial = new THREE.MeshPhongMaterial({
 251         color: 0xFA1A09, 
 252         side: THREE.DoubleSide,
 253         shininess: 100.0
 254     });
 255 
 256     const chamber = new THREE.Mesh(chamberGeometry, chamberMaterial);
 257     chassis.add(chamber);
 258     chamber.position.set(0, (chassisHeight + cabinWallThickness)/2, chassisOffset);
 259 
 260     const cabinGeometry = buildCabin();
 261     const cabin = new THREE.Mesh(cabinGeometry, chamberMaterial);
 262     chassis.add(cabin);
 263     cabin.position.set(0,
 264         (chassisHeight + cabinWallThickness)/2,
 265         -steamChamberLen+(cabinLen/2)+chassisOffset);
 266 
 267     const cabinRoofGeometry = buildCabinRoof();
 268     const roofMaterial = new THREE.MeshPhongMaterial({
 269         color: 0xFBEC50, 
 270         side: THREE.DoubleSide,
 271         shininess: 100.0
 272     });
 273 
 274     const cabinRoof = new THREE.Mesh(cabinRoofGeometry, roofMaterial);
 275     cabin.add(cabinRoof);
 276     cabinRoof.position.set(0, cabinHeight+cabinRoofHeight+cabinWallThickness/2, 0);
 277 
 278     const a1 = buildTrainAxe();
 279     chassis.add(a1);
 280 
 281     const a2 = buildTrainAxe();
 282     chassis.add(a2);
 283 
 284     const a3 = buildTrainAxe(chassisMaterial);
 285     chassis.add(a3);
 286 
 287     a1.position.set(0, wheelOffset, -0.60);
 288     a2.position.set(0, wheelOffset, -0.60+wheelRad*2.5);
 289     a3.position.set(0, wheelOffset, -0.60-wheelRad*2.5);
 290 
 291     const cylinderLeft = new THREE.CylinderGeometry(1.25, 1.5, steamCylindersLen);
 292     cylinderLeft.rotateX(Math.PI/2);
 293     cylinderLeft.translate(steamChamberRad-0.25, -.25, steamChamberLen-steamCylindersLen/1.5);
 294 
 295     const cylinderRight = new THREE.CylinderGeometry(1.25, 1.5, steamCylindersLen);
 296     cylinderRight.rotateX(Math.PI/2);
 297     cylinderRight.translate(-steamChamberRad+0.25, -.25, steamChamberLen-steamCylindersLen/1.5);
 298 
 299     const cylindersGeometry = BufferGeometryUtils.mergeGeometries([cylinderRight, cylinderLeft]);
 300     const cylindersMaterial = new THREE.MeshPhongMaterial({
 301         color: 0x393939, 
 302         side: THREE.DoubleSide,
 303         shininess: 100.0
 304     });
 305 
 306     chassis.add(new THREE.Mesh(cylindersGeometry, cylindersMaterial));
 307     chassis.position.set(0,-2,-2.75);
 308 
 309     const w1 = buildTrainWheel();
 310     w1.position.set(steamChamberRad-wheelThickness/2.1,0,0);
 311     a1.add(w1);
 312 
 313     const w2 = buildTrainWheel();
 314     w2.position.set(-steamChamberRad+wheelThickness/2.1,0,0);
 315     a1.add(w2);
 316 
 317     const w3 = buildTrainWheel();
 318     w3.position.set(steamChamberRad-wheelThickness/2.1,0,0);
 319     a2.add(w3);
 320 
 321     const w4 = buildTrainWheel();
 322     w4.position.set(-steamChamberRad+wheelThickness/2.1,0,);
 323     a2.add(w4);
 324 
 325     const w5 = buildTrainWheel();
 326     w5.position.set(steamChamberRad-wheelThickness/2.1,0,0);
 327     a3.add(w5);
 328 
 329     const w6 = buildTrainWheel();
 330     w6.position.set(-steamChamberRad+wheelThickness/2.1,0,0);
 331     a3.add(w6);
 332 
 333     const crankGeometry = new THREE.BoxGeometry(crankWidth, 0.5, crankLen);
 334 
 335     crankRight = new THREE.Mesh(crankGeometry, chassisMaterial);
 336     //crankRight.position.set(steamChamberRad, wheelOffset, crankOffset);
 337 
 338     crankLeft = new THREE.Mesh(crankGeometry, chassisMaterial);
 339     //crankLeft.position.set(-steamChamberRad, wheelOffset, crankOffset);
 340 
 341     chassis.add(crankLeft);
 342     chassis.add(crankRight);
 343 
 344     chassis.translateY(-wheelOffset);
 345 
 346     const lightRad = 1.10;
 347     const lightGeometry = new THREE.CylinderGeometry(lightRad, lightRad, 1, 32);
 348     lightGeometry.rotateX(Math.PI/2);
 349 
 350     const lightMaterial = new THREE.MeshPhongMaterial({
 351         color: 0x393939, 
 352         side: THREE.DoubleSide,
 353         shininess: 100.0,
 354         emissive: 0xf6d32d
 355     });
 356 
 357     const light = new THREE.Mesh(lightGeometry, lightMaterial);
 358     train.add(light)
 359     light.position.set(0,
 360         steamChamberRad+chassisOffset-lightRad/2-.30,
 361         (steamChamberLen+steamChamberEndLen)/2-.3);
 362 
 363     train.position.set(0, 2, 0);
 364     return train;
 365 }
 366 
 367 function buildScene() {
 368     console.log('Building scene');
 369 
 370     const train = buildTrain();
 371     scene.add(train);
 372 }
 373 
 374 function onTextureLoaded(key, texture) {
 375     texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
 376     textures[key].object = texture;
 377     console.log('Texture `' + key + '` loaded');
 378 }
 379 
 380 function mainLoop() {
 381     time += 0.05;
 382 
 383     requestAnimationFrame(mainLoop);
 384 
 385     crankLeft.position.set(-steamChamberRad-crankWidth/2,
 386         wheelOffset + 0.70*(Math.sin(time*Math.PI/2)),
 387         crankOffset - 0.70*(Math.cos(time*Math.PI/2)));
 388 
 389     crankRight.position.set(steamChamberRad+crankWidth/2,
 390         wheelOffset + 0.70*(Math.sin(time*Math.PI/2)),
 391         crankOffset - 0.70*(Math.cos(time*Math.PI/2)));
 392 
 393     renderer.render(scene, camera);
 394 }
 395 
 396 function main() {
 397     buildScene();
 398     mainLoop();
 399 }
 400 
 401 setupThreeJs();
 402 main();