From f52b7efa6f796dc337a6b5e26999c5fe27dab35c Mon Sep 17 00:00:00 2001 From: davidpkj Date: Tue, 13 Dec 2022 15:02:45 +0100 Subject: Add: assets & src --- assets/scene.glb | Bin 0 -> 2362204 bytes assets/skybox/skybottom.png | Bin 0 -> 214516 bytes assets/skybox/skycenter.png | Bin 0 -> 422131 bytes assets/skybox/skyleft.png | Bin 0 -> 446310 bytes assets/skybox/skymap.png | Bin 0 -> 2233710 bytes assets/skybox/skyright.png | Bin 0 -> 438950 bytes assets/skybox/skytop.png | Bin 0 -> 330320 bytes assets/skybox/skyveryright.png | Bin 0 -> 288036 bytes src/index.ts | 169 +++++++++++++++++++++++++++++++++++++++++ 9 files changed, 169 insertions(+) create mode 100644 assets/scene.glb create mode 100644 assets/skybox/skybottom.png create mode 100644 assets/skybox/skycenter.png create mode 100644 assets/skybox/skyleft.png create mode 100644 assets/skybox/skymap.png create mode 100644 assets/skybox/skyright.png create mode 100644 assets/skybox/skytop.png create mode 100644 assets/skybox/skyveryright.png create mode 100644 src/index.ts diff --git a/assets/scene.glb b/assets/scene.glb new file mode 100644 index 0000000..a86fe00 Binary files /dev/null and b/assets/scene.glb differ diff --git a/assets/skybox/skybottom.png b/assets/skybox/skybottom.png new file mode 100644 index 0000000..1bc0711 Binary files /dev/null and b/assets/skybox/skybottom.png differ diff --git a/assets/skybox/skycenter.png b/assets/skybox/skycenter.png new file mode 100644 index 0000000..55a836a Binary files /dev/null and b/assets/skybox/skycenter.png differ diff --git a/assets/skybox/skyleft.png b/assets/skybox/skyleft.png new file mode 100644 index 0000000..0332acb Binary files /dev/null and b/assets/skybox/skyleft.png differ diff --git a/assets/skybox/skymap.png b/assets/skybox/skymap.png new file mode 100644 index 0000000..bac8753 Binary files /dev/null and b/assets/skybox/skymap.png differ diff --git a/assets/skybox/skyright.png b/assets/skybox/skyright.png new file mode 100644 index 0000000..6fa0526 Binary files /dev/null and b/assets/skybox/skyright.png differ diff --git a/assets/skybox/skytop.png b/assets/skybox/skytop.png new file mode 100644 index 0000000..067489e Binary files /dev/null and b/assets/skybox/skytop.png differ diff --git a/assets/skybox/skyveryright.png b/assets/skybox/skyveryright.png new file mode 100644 index 0000000..b557a92 Binary files /dev/null and b/assets/skybox/skyveryright.png differ diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..a25502d --- /dev/null +++ b/src/index.ts @@ -0,0 +1,169 @@ +import * as THREE from "three"; +import { WEBGL } from "three/examples/jsm/WebGL"; +import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; +import { PointerLockControls } from "three/examples/jsm/controls/PointerLockControls"; + +import { CollisionCaster } from "./collisionCaster"; + +const clock: THREE.Clock = new THREE.Clock(true); +const acceleration: number = 9.8; +const speed: number = 50; +const mass: number = 100; + +let controls: PointerLockControls, renderer: THREE.WebGLRenderer, camera: THREE.PerspectiveCamera, scene: THREE.Scene, raycaster: THREE.Raycaster; +let movementDirection: Map = new Map(); +let direction = new THREE.Vector3(); +let velocity = new THREE.Vector3(); +let clips = []; + +const initialize = () => { + renderer = new THREE.WebGLRenderer({ antialias: true }); + renderer.setSize(window.innerWidth, window.innerHeight); + renderer.setPixelRatio(window.devicePixelRatio); + renderer.shadowMap.type = THREE.PCFSoftShadowMap; + renderer.shadowMap.enabled = true; + + document.body.appendChild(renderer.domElement); + + scene = new THREE.Scene(); + + initializeBackground(); + initializeStructures(); + initializeLighting(); + initializeViewer(); + + render(); +} + +const initializeBackground = () => { + const loader = new THREE.CubeTextureLoader(); + const texture = loader.load([ + '../assets/skybox/skyright.png', + '../assets/skybox/skyleft.png', + '../assets/skybox/skytop.png', + '../assets/skybox/skybottom.png', + '../assets/skybox/skycenter.png', + '../assets/skybox/skyveryright.png', + ]); + + scene.background = texture; +} + +const initializeStructures = () => { + const ground: THREE.Mesh = new THREE.Mesh(new THREE.PlaneGeometry(1000, 1000, 10, 10), new THREE.MeshPhongMaterial({ depthWrite: false, visible: false })); + ground.rotation.x = - Math.PI / 2; + ground.position.set(0, 0, 0); + ground.receiveShadow = true; + clips.push(ground); + scene.add(ground); + + const loader = new GLTFLoader(); + loader.load("../assets/scene.glb", (data) => { scene.add(data.scene); }); +} + +const initializeLighting = () => { + const intensity: number = 1; + const ambientLight: THREE.AmbientLight = new THREE.AmbientLight(0xFFFFFF, intensity); + const hemilight: THREE.HemisphereLight = new THREE.HemisphereLight(0x5D6DFF, 0xD99D80, intensity); + const dirlight: THREE.DirectionalLight = new THREE.DirectionalLight(0xFFFFFF, intensity); + dirlight.position.set(5, 10, 2); + + scene.add(ambientLight); + scene.add(hemilight); + scene.add(dirlight); + scene.add(dirlight.target); +} + +const initializeViewer = () => { + const fov = 45; + const aspect = 1920 / 1080; + camera = new THREE.PerspectiveCamera(fov, aspect); + camera.position.set(0, 0, 0); + + controls = new PointerLockControls(camera, renderer.domElement); + controls.getObject().position.set(10, 1, 0); + + scene.add(controls.getObject()); +} + +const applyMovement = (delta: number) => { + const left = (movementDirection["a"] || movementDirection["ArrowLeft"]) ? true : false; + const right = (movementDirection["d"] || movementDirection["ArrowRight"]) ? true : false; + const forward = (movementDirection["w"] || movementDirection["ArrowUp"]) ? true : false; + const backward = (movementDirection["s"] || movementDirection["ArrowDown"]) ? true : false; + + velocity.x -= velocity.x * acceleration * delta; + velocity.z -= velocity.z * acceleration * delta; + + direction.z = Number(forward) - Number(backward); + direction.x = Number(right) - Number(left); + direction.normalize(); + + if (forward || backward) velocity.z -= direction.z * speed * delta; + if (left || right) velocity.x -= direction.x * speed * delta; + + controls.moveForward(- velocity.z * delta); + controls.moveRight(- velocity.x * delta); +} + +const applyPhysics = (delta) => { + const collision = new CollisionCaster(camera.position, 0.4, clips); + + if (collision.down != 0) { + if (collision.down < 0.2) camera.position.setY(camera.position.y + 0.1); + } else { + camera.position.setY(camera.position.y - acceleration * delta); + } +} + +const render = () => { + requestAnimationFrame(render); + + const delta = clock.getDelta(); + + if (controls.isLocked) { + applyMovement(delta); + applyPhysics(delta); + } + + renderer.render(scene, camera); +} + +const changeMovement = (event: KeyboardEvent, down: boolean) => { + const exclude = ["F5", "F11", "F12", "Escape", "Control", "LeftShift", "Tab"]; + + if (exclude.includes(event.key)) return; + + event.stopPropagation(); + event.preventDefault(); + + movementDirection[event.key] = down; +} + +const togglePointerLock = () => { + if (controls.isLocked) { + controls.unlock(); + (document.querySelector("#pause") as HTMLElement).style.display = "block"; + } else { + controls.lock(); + (document.querySelector("#pause") as HTMLElement).style.display = "none"; + } +} + +const onWindowResize = () => { + renderer.setSize(window.innerWidth, window.innerHeight); + camera.aspect = window.innerWidth / window.innerHeight; + camera.updateProjectionMatrix(); +} + +window.addEventListener("keydown", (event) => { changeMovement(event, true); }, false); +window.addEventListener("keyup", (event) => { changeMovement(event, false); }, false); +window.addEventListener("click", togglePointerLock, false); +window.addEventListener("resize", onWindowResize, false); + +if (WEBGL.isWebGLAvailable()) { + initialize(); +} else { + const warning = WEBGL.getWebGLErrorMessage(); + document.body.appendChild(warning); +} -- cgit v1.2.3