102 lines
3.1 KiB
JavaScript
102 lines
3.1 KiB
JavaScript
import * as THREE from 'three';
|
|
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
|
|
import { PointerLockControls } from 'three/addons/controls/PointerLockControls.js';
|
|
|
|
const next_url = 'https://3dworldring.cjsatnarine.space/cjsatnarine_study/next';
|
|
const prev_url = 'https://3dworldring.cjsatnarine.space/cjsatnarine_study/previous';
|
|
|
|
const renderer = new THREE.WebGLRenderer();
|
|
|
|
const scene = new THREE.Scene();
|
|
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
|
|
const light = new THREE.AmbientLight(0xFFFFFF, 2);
|
|
|
|
const study = new GLTFLoader();
|
|
|
|
const controls = new PointerLockControls(camera, document.body);
|
|
const clock = new THREE.Clock();
|
|
const keymap = {};
|
|
const pointer = new THREE.Vector2();
|
|
const raycaster = new THREE.Raycaster();
|
|
|
|
init();
|
|
|
|
function init() {
|
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
|
|
document.body.appendChild(renderer.domElement);
|
|
|
|
scene.background = new THREE.Color(0x000000);
|
|
scene.add(camera);
|
|
|
|
scene.add(light);
|
|
|
|
camera.position.y = 1.5;
|
|
|
|
study.load('../assets/study.glb', function(gltf) {
|
|
scene.add(gltf.scene);
|
|
|
|
function onPointerDown(event) {
|
|
if (controls.isLocked) {
|
|
pointer.set(0, 0);
|
|
raycaster.setFromCamera(pointer, camera);
|
|
}
|
|
else {
|
|
const rect = renderer.domElement.getBoundingClientRect();
|
|
pointer.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
|
|
pointer.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
|
|
raycaster.setFromCamera(pointer, camera);
|
|
}
|
|
|
|
const intersects = raycaster.intersectObject(gltf.scene, true);
|
|
if (!intersects.length) return;
|
|
|
|
for (let i = 0; i < intersects.length; i++) {
|
|
let object = intersects[i].object;
|
|
|
|
while (object && object !== gltf.scene) {
|
|
if (object.name === 'Next') {
|
|
window.open(next_url);
|
|
return;
|
|
}
|
|
|
|
if (object.name === 'Previous') {
|
|
window.open(prev_url);
|
|
return;
|
|
}
|
|
object = object.parent;
|
|
}
|
|
}
|
|
}
|
|
window.addEventListener('pointerdown', onPointerDown, false);
|
|
|
|
}, undefined, function(error) {
|
|
console.error(error);
|
|
});
|
|
|
|
document.addEventListener('click', () => { controls.lock(); });
|
|
|
|
const onDocumentKey = (e) => { keymap[e.code] = e.type === 'keydown'; };
|
|
document.addEventListener('keydown', onDocumentKey, false);
|
|
document.addEventListener('keyup', onDocumentKey, false);
|
|
}
|
|
|
|
|
|
function animate() {
|
|
const delta = clock.getDelta();
|
|
|
|
if (controls.isLocked) {
|
|
if (keymap['KeyW']) controls.moveForward(delta * 5);
|
|
if (keymap['KeyS']) controls.moveForward(-delta * 5);
|
|
if (keymap['KeyA']) controls.moveRight(-delta * 5);
|
|
if (keymap['KeyD']) controls.moveRight(delta * 5);
|
|
}
|
|
|
|
renderer.render(scene, camera);
|
|
|
|
}
|
|
|
|
renderer.setAnimationLoop(animate);
|
|
|
|
|