Feature: main window

This commit is contained in:
Dejvino 2025-11-21 22:44:18 +01:00
parent ea813c88be
commit 1d1c8da558

View File

@ -132,6 +132,62 @@ export class StainedGlass extends SceneFeature {
return geometry;
};
const createProceduralRoseWindowGeometry = (mainColor, radius) => {
const segments = 32; // Number of radial segments
const rings = 5;
const vertices = [];
const colors = [];
const normals = [];
const randomnessFactor = 0.4;
const addTriangle = (v1, v2, v3, isBorder = false) => {
let segmentColor;
const rand = Math.random();
if (rand < 0.05) { // 5% chance for a "lead line"
segmentColor = new THREE.Color(0x333333);
} else if (isBorder && rand < 0.6) {
segmentColor = mainColor.clone().offsetHSL(0, 0, -0.1);
} else if (isBorder) {
segmentColor = colorPalette[Math.floor(Math.random() * colorPalette.length)].clone().offsetHSL(0, 0, -0.1);
} else {
if (rand < 0.85) {
segmentColor = mainColor.clone();
segmentColor.offsetHSL((Math.random() - 0.5) * 0.1, (Math.random() - 0.5) * 0.3, (Math.random() - 0.5) * 0.2);
} else {
segmentColor = colorPalette[Math.floor(Math.random() * colorPalette.length)];
}
}
vertices.push(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, v3.x, v3.y, v3.z);
colors.push(segmentColor.r, segmentColor.g, segmentColor.b, segmentColor.r, segmentColor.g, segmentColor.b, segmentColor.r, segmentColor.g, segmentColor.b);
const edge1 = new THREE.Vector3().subVectors(v2, v1);
const edge2 = new THREE.Vector3().subVectors(v3, v1);
const faceNormal = new THREE.Vector3().crossVectors(edge1, edge2).normalize();
const randomVec = new THREE.Vector3(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5).normalize();
faceNormal.add(randomVec.multiplyScalar(randomnessFactor)).normalize();
normals.push(faceNormal.x, faceNormal.y, faceNormal.z, faceNormal.x, faceNormal.y, faceNormal.z, faceNormal.x, faceNormal.y, faceNormal.z);
};
for (let r = 0; r < rings; r++) {
for (let s = 0; s < segments; s++) {
const angle1 = (s / segments) * Math.PI * 2;
const angle2 = ((s + 1) / segments) * Math.PI * 2;
const v1 = new THREE.Vector3(Math.cos(angle1) * (r * radius / rings), Math.sin(angle1) * (r * radius / rings), 0);
const v2 = new THREE.Vector3(Math.cos(angle2) * (r * radius / rings), Math.sin(angle2) * (r * radius / rings), 0);
const v3 = new THREE.Vector3(Math.cos(angle1) * ((r + 1) * radius / rings), Math.sin(angle1) * ((r + 1) * radius / rings), 0);
const v4 = new THREE.Vector3(Math.cos(angle2) * ((r + 1) * radius / rings), Math.sin(angle2) * ((r + 1) * radius / rings), 0);
addTriangle(v1, v2, v3, r === rings - 1);
addTriangle(v2, v4, v3, r === rings - 1);
}
}
const geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));
geometry.setAttribute('normal', new THREE.Float32BufferAttribute(normals, 3));
return geometry;
};
// --- Create and Place Windows ---
const createAndPlaceWindow = (position, rotationY) => {
// Pick a main color for this entire window
@ -164,6 +220,16 @@ export class StainedGlass extends SceneFeature {
// Right side of Nave
createAndPlaceWindow(new THREE.Vector3(naveWidth / 2 - 0.01, y, z), -Math.PI / 2);
}
// --- Add Huge Rose Window behind the stage ---
const roseWindowRadius = naveWidth / 2 - 1; // Almost as wide as the nave
const roseWindowMainColor = colorPalette[Math.floor(Math.random() * colorPalette.length)];
const roseWindowGeo = createProceduralRoseWindowGeometry(roseWindowMainColor, roseWindowRadius);
const roseWindowMesh = new THREE.Mesh(roseWindowGeo, material);
roseWindowMesh.position.set(0, naveHeight - 2, -length / 2 + 0.05);
state.scene.add(roseWindowMesh);
this.windows.push(roseWindowMesh);
}
update(deltaTime) {