120 lines
4.0 KiB
JavaScript
120 lines
4.0 KiB
JavaScript
import * as THREE from 'three';
|
|
import { state } from '../state.js';
|
|
|
|
let doorGroupPanel;
|
|
let outsideMaterial; // Declare outsideMaterial globally
|
|
let glowIntensity = 0.0;
|
|
let glowDirection = 1; // 1 for increasing, -1 for decreasing
|
|
|
|
const DOOR_STATES = {
|
|
RESTING: 'resting',
|
|
OPENING: 'opening',
|
|
CLOSING: 'closing',
|
|
};
|
|
let doorState = DOOR_STATES.RESTING;
|
|
let stateTimer = 0;
|
|
|
|
export function createDoor(x, z, rotY) {
|
|
const doorWidth = 1;
|
|
|
|
const doorGroup = new THREE.Group();
|
|
doorGroup.position.set(x, 1.1, z); // Centered vertically for a 2.2m door
|
|
doorGroup.rotation.set(0, rotY, 0);
|
|
|
|
// Door Frame
|
|
const frameMaterial = new THREE.MeshPhongMaterial({ color: 0x473e3a }); // Dark wood for frame
|
|
const frameTop = new THREE.Mesh(new THREE.BoxGeometry(1.2, 0.1, 0.15), frameMaterial);
|
|
frameTop.position.set(0, 1.15, 0);
|
|
frameTop.castShadow = true;
|
|
doorGroup.add(frameTop);
|
|
|
|
const frameLeft = new THREE.Mesh(new THREE.BoxGeometry(0.1, 2.3, 0.15), frameMaterial);
|
|
frameLeft.position.set(-0.55, 0.05, 0);
|
|
frameLeft.castShadow = true;
|
|
doorGroup.add(frameLeft);
|
|
|
|
const frameRight = new THREE.Mesh(new THREE.BoxGeometry(0.1, 2.3, 0.15), frameMaterial);
|
|
frameRight.position.set(0.55, 0.05, 0);
|
|
frameRight.castShadow = true;
|
|
doorGroup.add(frameRight);
|
|
|
|
// Outside darkness
|
|
outsideMaterial = new THREE.MeshPhongMaterial({ color: 0x150505, emissive: 0x000000, shininess: 50 });
|
|
const outside = new THREE.Mesh(new THREE.BoxGeometry(doorWidth, 2.2, 0.04), outsideMaterial);
|
|
outside.position.set(0, 0, 0);
|
|
doorGroup.add(outside);
|
|
|
|
// Door group
|
|
doorGroupPanel = new THREE.Group();
|
|
// Main Door Panel
|
|
const doorMaterial = new THREE.MeshPhongMaterial({ color: 0x8b5a2b, shininess: 10 }); // Lighter wood for door
|
|
const door = new THREE.Mesh(new THREE.BoxGeometry(doorWidth, 2.2, 0.08), doorMaterial);
|
|
door.position.set(doorWidth/2, 0, 0);
|
|
door.castShadow = true;
|
|
door.receiveShadow = true;
|
|
doorGroupPanel.add(door);
|
|
|
|
// Door Knob
|
|
const knobMaterial = new THREE.MeshPhongMaterial({ color: 0xd4af37, shininess: 100 }); // Gold/Brass
|
|
const knob = new THREE.Mesh(new THREE.SphereGeometry(0.05, 16, 16), knobMaterial);
|
|
knob.position.set(doorWidth/2 + 0.4, 0, 0.06); // Position on the right side of the door
|
|
knob.castShadow = true;
|
|
doorGroupPanel.add(knob);
|
|
doorGroupPanel.position.x = -doorWidth/2;
|
|
doorGroupPanel.rotation.y = 0;
|
|
|
|
doorGroup.add(doorGroupPanel);
|
|
|
|
state.scene.add(doorGroup);
|
|
}
|
|
|
|
export function updateDoor() {
|
|
const speed = 0.0002;
|
|
const minAngle = 0;
|
|
const maxAngle = -0.7;
|
|
|
|
stateTimer -= 1 / 60; // Assuming 60fps
|
|
|
|
if (stateTimer <= 0) {
|
|
const nextState = Math.random();
|
|
if (nextState < 0.4) {
|
|
doorState = DOOR_STATES.RESTING;
|
|
stateTimer = 2 + Math.random() * 5;
|
|
} else if (nextState < 0.7) {
|
|
doorState = DOOR_STATES.OPENING;
|
|
stateTimer = 2 + Math.random() * 4;
|
|
} else {
|
|
doorState = DOOR_STATES.CLOSING;
|
|
stateTimer = 3 + Math.random() * 3;
|
|
}
|
|
}
|
|
|
|
switch (doorState) {
|
|
case DOOR_STATES.OPENING:
|
|
if (doorGroupPanel.rotation.y > maxAngle) {
|
|
doorGroupPanel.rotation.y -= speed;
|
|
}
|
|
break;
|
|
case DOOR_STATES.CLOSING:
|
|
if (doorGroupPanel.rotation.y < minAngle) {
|
|
doorGroupPanel.rotation.y += speed;
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Outside material pulsating glow
|
|
if (outsideMaterial) {
|
|
const glowMin = 0.001;
|
|
const glowMax = 0.01;
|
|
const glowSpeed = 0.0001; // Speed of the pulsation
|
|
glowIntensity += glowDirection * glowSpeed;
|
|
if (glowIntensity >= glowMax) {
|
|
glowIntensity = glowMax;
|
|
glowDirection = -1;
|
|
} else if (glowIntensity <= glowMin) {
|
|
glowIntensity = glowMin;
|
|
glowDirection = 1;
|
|
}
|
|
outsideMaterial.emissive.setRGB(glowIntensity, 0, 0);
|
|
}
|
|
} |