Feature: main window
This commit is contained in:
parent
ea813c88be
commit
1d1c8da558
@ -132,6 +132,62 @@ export class StainedGlass extends SceneFeature {
|
|||||||
return geometry;
|
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 ---
|
// --- Create and Place Windows ---
|
||||||
const createAndPlaceWindow = (position, rotationY) => {
|
const createAndPlaceWindow = (position, rotationY) => {
|
||||||
// Pick a main color for this entire window
|
// Pick a main color for this entire window
|
||||||
@ -164,6 +220,16 @@ export class StainedGlass extends SceneFeature {
|
|||||||
// Right side of Nave
|
// Right side of Nave
|
||||||
createAndPlaceWindow(new THREE.Vector3(naveWidth / 2 - 0.01, y, z), -Math.PI / 2);
|
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) {
|
update(deltaTime) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user