diff --git a/party-cathedral/src/scene/pews.js b/party-cathedral/src/scene/pews.js index dee03d4..241baac 100644 --- a/party-cathedral/src/scene/pews.js +++ b/party-cathedral/src/scene/pews.js @@ -1 +1,91 @@ -// This file will contain the Three.js code for creating rows of pews (seats) on the sides of the cathedral. \ No newline at end of file +import * as THREE from 'three'; +import { state } from '../state.js'; +import { SceneFeature } from './SceneFeature.js'; +import sceneFeatureManager from './SceneFeatureManager.js'; +import woodTextureUrl from '/textures/wood.png'; + +export class Pews extends SceneFeature { + constructor() { + super(); + sceneFeatureManager.register(this); + } + + init() { + // --- Dimensions from room-walls.js for positioning --- + const length = 40; + const naveWidth = 12; + const aisleWidth = 6; + + // --- Pew Properties --- + const pewLength = aisleWidth - 2.5; // A bit shorter than the aisle is wide + const seatDepth = 0.5; + const seatHeight = 0.5; + const backHeight = 1.0; + const numPewsPerSide = 15; + const pewSpacing = (length - 10) / numPewsPerSide; // Leave space at the front and back + + // --- Material --- + const woodTexture = state.loader.load(woodTextureUrl); + const woodMaterial = new THREE.MeshStandardMaterial({ + map: woodTexture, + roughness: 0.8, + metalness: 0.1, + }); + + // --- Reusable Pew Model --- + const createPew = () => { + const pewGroup = new THREE.Group(); + + // Seat + const seatGeo = new THREE.BoxGeometry(pewLength, seatDepth, 0.1); + const seat = new THREE.Mesh(seatGeo, woodMaterial); + seat.rotation.x = Math.PI / 2; + seat.position.set(0, seatHeight, 0); + pewGroup.add(seat); + + // Backrest + const backGeo = new THREE.BoxGeometry(pewLength, backHeight, 0.1); + const backrest = new THREE.Mesh(backGeo, woodMaterial); + backrest.position.set(0, seatHeight + backHeight / 2, -seatDepth / 2); + pewGroup.add(backrest); + + // Side Supports + const supportHeight = seatHeight + backHeight; + const supportDepth = seatDepth + 0.1; + const supportGeo = new THREE.BoxGeometry(0.1, supportHeight, supportDepth); + const leftSupport = new THREE.Mesh(supportGeo, woodMaterial); + leftSupport.position.set(-pewLength / 2, supportHeight / 2, -supportDepth / 2 + 0.1); + const rightSupport = new THREE.Mesh(supportGeo, woodMaterial); + rightSupport.position.set(pewLength / 2, supportHeight / 2, -supportDepth / 2 + 0.1); + pewGroup.add(leftSupport, rightSupport); + + pewGroup.traverse(child => { + if (child.isMesh) { + child.castShadow = true; + child.receiveShadow = true; + } + }); + + return pewGroup; + }; + + // --- Place Pews in Aisles --- + for (let i = 0; i < numPewsPerSide; i++) { + const z = -length / 2 + 8 + (i * pewSpacing); + + // Left Aisle + const pewLeft = createPew(); + pewLeft.position.set(-naveWidth / 2 - aisleWidth / 2, 0, z); + pewLeft.rotation.y = Math.PI; // Turn around 180 degrees + state.scene.add(pewLeft); + + // Right Aisle + const pewRight = createPew(); + pewRight.position.set(naveWidth / 2 + aisleWidth / 2, 0, z); + pewRight.rotation.y = Math.PI; // Turn around 180 degrees + state.scene.add(pewRight); + } + } +} + +new Pews(); \ No newline at end of file diff --git a/party-cathedral/src/scene/root.js b/party-cathedral/src/scene/root.js index 29c0139..6240586 100644 --- a/party-cathedral/src/scene/root.js +++ b/party-cathedral/src/scene/root.js @@ -5,6 +5,7 @@ import sceneFeatureManager from './SceneFeatureManager.js'; // Scene Features registered here: import { RoomWalls } from './room-walls.js'; import { LightBall } from './light-ball.js'; +import { Pews } from './pews.js'; // Scene Features ^^^ // --- Scene Modeling Function ---