You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					363 lines
				
				9.2 KiB
			
		
		
			
		
	
	
					363 lines
				
				9.2 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								<!-- Licensed under a BSD license. See license.html for license -->
							 | 
						||
| 
								 | 
							
								<!DOCTYPE html>
							 | 
						||
| 
								 | 
							
								<html>
							 | 
						||
| 
								 | 
							
								  <head>
							 | 
						||
| 
								 | 
							
								    <meta charset="utf-8">
							 | 
						||
| 
								 | 
							
								    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
							 | 
						||
| 
								 | 
							
								    <title>Three.js - Game - Just Player</title>
							 | 
						||
| 
								 | 
							
								    <style>
							 | 
						||
| 
								 | 
							
								    html {
							 | 
						||
| 
								 | 
							
								      box-sizing: border-box;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    *, *:before, *:after {
							 | 
						||
| 
								 | 
							
								      box-sizing: inherit;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    html, body {
							 | 
						||
| 
								 | 
							
								        margin: 0;
							 | 
						||
| 
								 | 
							
								        height: 100%;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    #c {
							 | 
						||
| 
								 | 
							
								        width: 100%;
							 | 
						||
| 
								 | 
							
								        height: 100%;
							 | 
						||
| 
								 | 
							
								        display: block;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    #loading {
							 | 
						||
| 
								 | 
							
								      position: absolute;
							 | 
						||
| 
								 | 
							
								      left: 0;
							 | 
						||
| 
								 | 
							
								      top: 0;
							 | 
						||
| 
								 | 
							
								      width: 100%;
							 | 
						||
| 
								 | 
							
								      height: 100%;
							 | 
						||
| 
								 | 
							
								      display: flex;
							 | 
						||
| 
								 | 
							
								      align-items: center;
							 | 
						||
| 
								 | 
							
								      justify-content: center;
							 | 
						||
| 
								 | 
							
								      text-align: center;
							 | 
						||
| 
								 | 
							
								      font-size: xx-large;
							 | 
						||
| 
								 | 
							
								      font-family: sans-serif;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    #loading>div>div {
							 | 
						||
| 
								 | 
							
								      padding: 2px;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    .progress {
							 | 
						||
| 
								 | 
							
								      width: 50vw;
							 | 
						||
| 
								 | 
							
								      border: 1px solid black;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    #progressbar {
							 | 
						||
| 
								 | 
							
								      width: 0%;
							 | 
						||
| 
								 | 
							
								      transition: width ease-out .5s;
							 | 
						||
| 
								 | 
							
								      height: 1em;
							 | 
						||
| 
								 | 
							
								      background-color: #888;
							 | 
						||
| 
								 | 
							
								      background-image: linear-gradient(
							 | 
						||
| 
								 | 
							
								        -45deg,
							 | 
						||
| 
								 | 
							
								        rgba(255, 255, 255, .5) 25%,
							 | 
						||
| 
								 | 
							
								        transparent 25%,
							 | 
						||
| 
								 | 
							
								        transparent 50%,
							 | 
						||
| 
								 | 
							
								        rgba(255, 255, 255, .5) 50%,
							 | 
						||
| 
								 | 
							
								        rgba(255, 255, 255, .5) 75%,
							 | 
						||
| 
								 | 
							
								        transparent 75%,
							 | 
						||
| 
								 | 
							
								        transparent
							 | 
						||
| 
								 | 
							
								      );
							 | 
						||
| 
								 | 
							
								      background-size: 50px 50px;
							 | 
						||
| 
								 | 
							
								      animation: progressanim 2s linear infinite;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @keyframes progressanim {
							 | 
						||
| 
								 | 
							
								      0% {
							 | 
						||
| 
								 | 
							
								        background-position: 50px 50px;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      100% {
							 | 
						||
| 
								 | 
							
								        background-position: 0 0;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  </style>
							 | 
						||
| 
								 | 
							
								  </head>
							 | 
						||
| 
								 | 
							
								  <body>
							 | 
						||
| 
								 | 
							
								    <canvas id="c"></canvas>
							 | 
						||
| 
								 | 
							
								    <div id="loading">
							 | 
						||
| 
								 | 
							
								      <div>
							 | 
						||
| 
								 | 
							
								        <div>...loading...</div>
							 | 
						||
| 
								 | 
							
								        <div class="progress"><div id="progressbar"></div></div>
							 | 
						||
| 
								 | 
							
								      </div>
							 | 
						||
| 
								 | 
							
								    </div>
							 | 
						||
| 
								 | 
							
								  </body>
							 | 
						||
| 
								 | 
							
								<!-- Import maps polyfill -->
							 | 
						||
| 
								 | 
							
								<!-- Remove this when import maps will be widely supported -->
							 | 
						||
| 
								 | 
							
								<script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<script type="importmap">
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  "imports": {
							 | 
						||
| 
								 | 
							
								    "three": "../../build/three.module.js",
							 | 
						||
| 
								 | 
							
								    "three/addons/": "../../examples/jsm/"
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								</script>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<script type="module">
							 | 
						||
| 
								 | 
							
								import * as THREE from 'three';
							 | 
						||
| 
								 | 
							
								import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
							 | 
						||
| 
								 | 
							
								import {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';
							 | 
						||
| 
								 | 
							
								import * as SkeletonUtils from 'three/addons/utils/SkeletonUtils.js';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function main() {
							 | 
						||
| 
								 | 
							
								  const canvas = document.querySelector('#c');
							 | 
						||
| 
								 | 
							
								  const renderer = new THREE.WebGLRenderer({canvas});
							 | 
						||
| 
								 | 
							
								  renderer.outputEncoding = THREE.sRGBEncoding;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const fov = 45;
							 | 
						||
| 
								 | 
							
								  const aspect = 2;  // the canvas default
							 | 
						||
| 
								 | 
							
								  const near = 0.1;
							 | 
						||
| 
								 | 
							
								  const far = 1000;
							 | 
						||
| 
								 | 
							
								  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
							 | 
						||
| 
								 | 
							
								  camera.position.set(0, 40, 80);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const controls = new OrbitControls(camera, canvas);
							 | 
						||
| 
								 | 
							
								  controls.target.set(0, 5, 0);
							 | 
						||
| 
								 | 
							
								  controls.update();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const scene = new THREE.Scene();
							 | 
						||
| 
								 | 
							
								  scene.background = new THREE.Color('white');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function addLight(...pos) {
							 | 
						||
| 
								 | 
							
								    const color = 0xFFFFFF;
							 | 
						||
| 
								 | 
							
								    const intensity = 0.8;
							 | 
						||
| 
								 | 
							
								    const light = new THREE.DirectionalLight(color, intensity);
							 | 
						||
| 
								 | 
							
								    light.position.set(...pos);
							 | 
						||
| 
								 | 
							
								    scene.add(light);
							 | 
						||
| 
								 | 
							
								    scene.add(light.target);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  addLight(5, 5, 2);
							 | 
						||
| 
								 | 
							
								  addLight(-5, 5, 5);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const manager = new THREE.LoadingManager();
							 | 
						||
| 
								 | 
							
								  manager.onLoad = init;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const progressbarElem = document.querySelector('#progressbar');
							 | 
						||
| 
								 | 
							
								  manager.onProgress = (url, itemsLoaded, itemsTotal) => {
							 | 
						||
| 
								 | 
							
								    progressbarElem.style.width = `${itemsLoaded / itemsTotal * 100 | 0}%`;
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const models = {
							 | 
						||
| 
								 | 
							
								    pig:    { url: 'resources/models/animals/Pig.gltf' },
							 | 
						||
| 
								 | 
							
								    cow:    { url: 'resources/models/animals/Cow.gltf' },
							 | 
						||
| 
								 | 
							
								    llama:  { url: 'resources/models/animals/Llama.gltf' },
							 | 
						||
| 
								 | 
							
								    pug:    { url: 'resources/models/animals/Pug.gltf' },
							 | 
						||
| 
								 | 
							
								    sheep:  { url: 'resources/models/animals/Sheep.gltf' },
							 | 
						||
| 
								 | 
							
								    zebra:  { url: 'resources/models/animals/Zebra.gltf' },
							 | 
						||
| 
								 | 
							
								    horse:  { url: 'resources/models/animals/Horse.gltf' },
							 | 
						||
| 
								 | 
							
								    knight: { url: 'resources/models/knight/KnightCharacter.gltf' },
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    const gltfLoader = new GLTFLoader(manager);
							 | 
						||
| 
								 | 
							
								    for (const model of Object.values(models)) {
							 | 
						||
| 
								 | 
							
								      gltfLoader.load(model.url, (gltf) => {
							 | 
						||
| 
								 | 
							
								        model.gltf = gltf;
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function prepModelsAndAnimations() {
							 | 
						||
| 
								 | 
							
								    Object.values(models).forEach(model => {
							 | 
						||
| 
								 | 
							
								      const animsByName = {};
							 | 
						||
| 
								 | 
							
								      model.gltf.animations.forEach((clip) => {
							 | 
						||
| 
								 | 
							
								        animsByName[clip.name] = clip;
							 | 
						||
| 
								 | 
							
								        // Should really fix this in .blend file
							 | 
						||
| 
								 | 
							
								        if (clip.name === 'Walk') {
							 | 
						||
| 
								 | 
							
								          clip.duration /= 2;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								      model.animations = animsByName;
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function removeArrayElement(array, element) {
							 | 
						||
| 
								 | 
							
								    const ndx = array.indexOf(element);
							 | 
						||
| 
								 | 
							
								    if (ndx >= 0) {
							 | 
						||
| 
								 | 
							
								      array.splice(ndx, 1);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  class SafeArray {
							 | 
						||
| 
								 | 
							
								    constructor() {
							 | 
						||
| 
								 | 
							
								      this.array = [];
							 | 
						||
| 
								 | 
							
								      this.addQueue = [];
							 | 
						||
| 
								 | 
							
								      this.removeQueue = new Set();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    get isEmpty() {
							 | 
						||
| 
								 | 
							
								      return this.addQueue.length + this.array.length > 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    add(element) {
							 | 
						||
| 
								 | 
							
								      this.addQueue.push(element);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    remove(element) {
							 | 
						||
| 
								 | 
							
								      this.removeQueue.add(element);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    forEach(fn) {
							 | 
						||
| 
								 | 
							
								      this._addQueued();
							 | 
						||
| 
								 | 
							
								      this._removeQueued();
							 | 
						||
| 
								 | 
							
								      for (const element of this.array) {
							 | 
						||
| 
								 | 
							
								        if (this.removeQueue.has(element)) {
							 | 
						||
| 
								 | 
							
								          continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        fn(element);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      this._removeQueued();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    _addQueued() {
							 | 
						||
| 
								 | 
							
								      if (this.addQueue.length) {
							 | 
						||
| 
								 | 
							
								        this.array.splice(this.array.length, 0, ...this.addQueue);
							 | 
						||
| 
								 | 
							
								        this.addQueue = [];
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    _removeQueued() {
							 | 
						||
| 
								 | 
							
								      if (this.removeQueue.size) {
							 | 
						||
| 
								 | 
							
								        this.array = this.array.filter(element => !this.removeQueue.has(element));
							 | 
						||
| 
								 | 
							
								        this.removeQueue.clear();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  class GameObjectManager {
							 | 
						||
| 
								 | 
							
								    constructor() {
							 | 
						||
| 
								 | 
							
								      this.gameObjects = new SafeArray();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    createGameObject(parent, name) {
							 | 
						||
| 
								 | 
							
								      const gameObject = new GameObject(parent, name);
							 | 
						||
| 
								 | 
							
								      this.gameObjects.add(gameObject);
							 | 
						||
| 
								 | 
							
								      return gameObject;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    removeGameObject(gameObject) {
							 | 
						||
| 
								 | 
							
								      this.gameObjects.remove(gameObject);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    update() {
							 | 
						||
| 
								 | 
							
								      this.gameObjects.forEach(gameObject => gameObject.update());
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const globals = {
							 | 
						||
| 
								 | 
							
								    time: 0,
							 | 
						||
| 
								 | 
							
								    deltaTime: 0,
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								  const gameObjectManager = new GameObjectManager();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  class GameObject {
							 | 
						||
| 
								 | 
							
								    constructor(parent, name) {
							 | 
						||
| 
								 | 
							
								      this.name = name;
							 | 
						||
| 
								 | 
							
								      this.components = [];
							 | 
						||
| 
								 | 
							
								      this.transform = new THREE.Object3D();
							 | 
						||
| 
								 | 
							
								      parent.add(this.transform);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    addComponent(ComponentType, ...args) {
							 | 
						||
| 
								 | 
							
								      const component = new ComponentType(this, ...args);
							 | 
						||
| 
								 | 
							
								      this.components.push(component);
							 | 
						||
| 
								 | 
							
								      return component;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    removeComponent(component) {
							 | 
						||
| 
								 | 
							
								      removeArrayElement(this.components, component);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    getComponent(ComponentType) {
							 | 
						||
| 
								 | 
							
								      return this.components.find(c => c instanceof ComponentType);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    update() {
							 | 
						||
| 
								 | 
							
								      for (const component of this.components) {
							 | 
						||
| 
								 | 
							
								        component.update();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // Base for all components
							 | 
						||
| 
								 | 
							
								  class Component {
							 | 
						||
| 
								 | 
							
								    constructor(gameObject) {
							 | 
						||
| 
								 | 
							
								      this.gameObject = gameObject;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    update() {
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  class SkinInstance extends Component {
							 | 
						||
| 
								 | 
							
								    constructor(gameObject, model) {
							 | 
						||
| 
								 | 
							
								      super(gameObject);
							 | 
						||
| 
								 | 
							
								      this.model = model;
							 | 
						||
| 
								 | 
							
								      this.animRoot = SkeletonUtils.clone(this.model.gltf.scene);
							 | 
						||
| 
								 | 
							
								      this.mixer = new THREE.AnimationMixer(this.animRoot);
							 | 
						||
| 
								 | 
							
								      gameObject.transform.add(this.animRoot);
							 | 
						||
| 
								 | 
							
								      this.actions = {};
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    setAnimation(animName) {
							 | 
						||
| 
								 | 
							
								      const clip = this.model.animations[animName];
							 | 
						||
| 
								 | 
							
								      // turn off all current actions
							 | 
						||
| 
								 | 
							
								      for (const action of Object.values(this.actions)) {
							 | 
						||
| 
								 | 
							
								        action.enabled = false;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      // get or create existing action for clip
							 | 
						||
| 
								 | 
							
								      const action = this.mixer.clipAction(clip);
							 | 
						||
| 
								 | 
							
								      action.enabled = true;
							 | 
						||
| 
								 | 
							
								      action.reset();
							 | 
						||
| 
								 | 
							
								      action.play();
							 | 
						||
| 
								 | 
							
								      this.actions[animName] = action;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    update() {
							 | 
						||
| 
								 | 
							
								      this.mixer.update(globals.deltaTime);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  class Player extends Component {
							 | 
						||
| 
								 | 
							
								    constructor(gameObject) {
							 | 
						||
| 
								 | 
							
								      super(gameObject);
							 | 
						||
| 
								 | 
							
								      const model = models.knight;
							 | 
						||
| 
								 | 
							
								      this.skinInstance = gameObject.addComponent(SkinInstance, model);
							 | 
						||
| 
								 | 
							
								      this.skinInstance.setAnimation('Run');
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function init() {
							 | 
						||
| 
								 | 
							
								    // hide the loading bar
							 | 
						||
| 
								 | 
							
								    const loadingElem = document.querySelector('#loading');
							 | 
						||
| 
								 | 
							
								    loadingElem.style.display = 'none';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    prepModelsAndAnimations();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      const gameObject = gameObjectManager.createGameObject(scene, 'player');
							 | 
						||
| 
								 | 
							
								      gameObject.addComponent(Player);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function resizeRendererToDisplaySize(renderer) {
							 | 
						||
| 
								 | 
							
								    const canvas = renderer.domElement;
							 | 
						||
| 
								 | 
							
								    const width = canvas.clientWidth;
							 | 
						||
| 
								 | 
							
								    const height = canvas.clientHeight;
							 | 
						||
| 
								 | 
							
								    const needResize = canvas.width !== width || canvas.height !== height;
							 | 
						||
| 
								 | 
							
								    if (needResize) {
							 | 
						||
| 
								 | 
							
								      renderer.setSize(width, height, false);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return needResize;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  let then = 0;
							 | 
						||
| 
								 | 
							
								  function render(now) {
							 | 
						||
| 
								 | 
							
								    // convert to seconds
							 | 
						||
| 
								 | 
							
								    globals.time = now * 0.001;
							 | 
						||
| 
								 | 
							
								    // make sure delta time isn't too big.
							 | 
						||
| 
								 | 
							
								    globals.deltaTime = Math.min(globals.time - then, 1 / 20);
							 | 
						||
| 
								 | 
							
								    then = globals.time;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (resizeRendererToDisplaySize(renderer)) {
							 | 
						||
| 
								 | 
							
								      const canvas = renderer.domElement;
							 | 
						||
| 
								 | 
							
								      camera.aspect = canvas.clientWidth / canvas.clientHeight;
							 | 
						||
| 
								 | 
							
								      camera.updateProjectionMatrix();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    gameObjectManager.update();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    renderer.render(scene, camera);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    requestAnimationFrame(render);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  requestAnimationFrame(render);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								main();
							 | 
						||
| 
								 | 
							
								</script>
							 | 
						||
| 
								 | 
							
								</html>
							 |