Feature: more colored windows
This commit is contained in:
parent
2811fdbbd8
commit
ea813c88be
@ -17,6 +17,7 @@ export class StainedGlass extends SceneFeature {
|
||||
const aisleWidth = 6;
|
||||
const totalWidth = naveWidth + 2 * aisleWidth;
|
||||
const aisleHeight = 8;
|
||||
const naveHeight = 15;
|
||||
|
||||
// --- Window Properties ---
|
||||
const windowWidth = 3;
|
||||
@ -35,14 +36,6 @@ export class StainedGlass extends SceneFeature {
|
||||
emissive: 0x000000, // We will control emissiveness via update
|
||||
});
|
||||
|
||||
// --- Procedural Geometry Generation ---
|
||||
const createProceduralWindowGeometry = () => {
|
||||
const segmentsX = 8;
|
||||
const segmentsY = 12;
|
||||
const vertices = [];
|
||||
const colors = [];
|
||||
const normals = [];
|
||||
|
||||
const colorPalette = [
|
||||
new THREE.Color(0x6A0DAD), // Purple
|
||||
new THREE.Color(0x00008B), // Dark Blue
|
||||
@ -53,12 +46,42 @@ export class StainedGlass extends SceneFeature {
|
||||
new THREE.Color(0x4B0082), // Indigo
|
||||
];
|
||||
|
||||
// --- Procedural Geometry Generation ---
|
||||
const createProceduralWindowGeometry = (mainColor) => {
|
||||
const secondColor = new THREE.Color((Math.random()), (Math.random()), (Math.random()));
|
||||
const segmentsX = 8;
|
||||
const segmentsY = 12;
|
||||
const vertices = [];
|
||||
const colors = [];
|
||||
const normals = [];
|
||||
|
||||
const randomnessFactor = 0.4; // How much to vary the normals
|
||||
|
||||
const addTriangle = (v1, v2, v3) => {
|
||||
const color = colorPalette[Math.floor(Math.random() * colorPalette.length)];
|
||||
const addTriangle = (v1, v2, v3, isBorder = false) => {
|
||||
let segmentColor;
|
||||
const rand = Math.random();
|
||||
|
||||
if (rand < 0.05) { // 5% chance for a "lead line"
|
||||
segmentColor = secondColor.clone();
|
||||
} else if (isBorder && rand < 0.6) { // 60% chance for border segments to be the main color
|
||||
segmentColor = mainColor.clone().offsetHSL(0, 0, -0.1); // Slightly darker border
|
||||
} else if (isBorder) { // Remaining chance for border to be an accent
|
||||
segmentColor = colorPalette[Math.floor(Math.random() * colorPalette.length)].clone().offsetHSL(0, 0, -0.1);
|
||||
}
|
||||
else { // Inner panels
|
||||
if (rand < 0.65) { // 65% chance (after lead lines) to be a variation of the main color
|
||||
segmentColor = mainColor.clone();
|
||||
// Slightly shift hue, saturation, and lightness
|
||||
segmentColor.offsetHSL((Math.random() - 0.5) * 0.2, (Math.random() - 0.5) * 0.2, (Math.random() - 0.5) * 0.4);
|
||||
} else if (rand < 0.8) {
|
||||
segmentColor = secondColor.clone().offsetHSL((Math.random() - 0.5) * 0.2, (Math.random() - 0.5) * 0.2, (Math.random() - 0.5) * 0.4);
|
||||
} else { // Remaining chance for a random accent color
|
||||
segmentColor = new THREE.Color((Math.random()), (Math.random()), (Math.random()));
|
||||
}
|
||||
}
|
||||
|
||||
vertices.push(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, v3.x, v3.y, v3.z);
|
||||
colors.push(color.r, color.g, color.b, color.r, color.g, color.b, color.r, color.g, color.b);
|
||||
colors.push(segmentColor.r, segmentColor.g, segmentColor.b, segmentColor.r, segmentColor.g, segmentColor.b, segmentColor.r, segmentColor.g, segmentColor.b);
|
||||
|
||||
// Calculate the base normal for the flat triangle face
|
||||
const edge1 = new THREE.Vector3().subVectors(v2, v1);
|
||||
@ -85,8 +108,9 @@ export class StainedGlass extends SceneFeature {
|
||||
const v2 = new THREE.Vector3(x2, y, 0);
|
||||
const v3 = new THREE.Vector3(x, y2, 0);
|
||||
const v4 = new THREE.Vector3(x2, y2, 0);
|
||||
addTriangle(v1, v2, v3);
|
||||
addTriangle(v2, v4, v3);
|
||||
const isBorder = i === 0 || i === segmentsX - 1 || j === 0;
|
||||
addTriangle(v1, v2, v3, isBorder);
|
||||
addTriangle(v2, v4, v3, isBorder);
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,7 +122,7 @@ export class StainedGlass extends SceneFeature {
|
||||
const v1 = archCenter;
|
||||
const v2 = new THREE.Vector3(Math.cos(angle1) * -windowWidth / 2, Math.sin(angle1) * windowArchHeight + windowBaseHeight, 0);
|
||||
const v3 = new THREE.Vector3(Math.cos(angle2) * -windowWidth / 2, Math.sin(angle2) * windowArchHeight + windowBaseHeight, 0);
|
||||
addTriangle(v1, v2, v3);
|
||||
addTriangle(v1, v2, v3, true); // Treat all arch segments as part of the border
|
||||
}
|
||||
|
||||
const geometry = new THREE.BufferGeometry();
|
||||
@ -110,7 +134,9 @@ export class StainedGlass extends SceneFeature {
|
||||
|
||||
// --- Create and Place Windows ---
|
||||
const createAndPlaceWindow = (position, rotationY) => {
|
||||
const geometry = createProceduralWindowGeometry(); // Generate unique geometry for each window
|
||||
// Pick a main color for this entire window
|
||||
const mainColor = colorPalette[Math.floor(Math.random() * colorPalette.length)];
|
||||
const geometry = createProceduralWindowGeometry(mainColor); // Generate unique geometry for each window
|
||||
const windowMesh = new THREE.Mesh(geometry, material);
|
||||
windowMesh.position.copy(position);
|
||||
windowMesh.rotation.y = rotationY;
|
||||
@ -127,6 +153,17 @@ export class StainedGlass extends SceneFeature {
|
||||
// Right side
|
||||
createAndPlaceWindow(new THREE.Vector3(totalWidth / 2 - 0.01, y, z), -Math.PI / 2);
|
||||
}
|
||||
|
||||
// --- Add Windows to the Nave/Clerestory Walls ---
|
||||
for (let i = 0; i < numWindowsPerSide * 2; i++) {
|
||||
const z = -length / 2 + windowSpacing / 2 * (i + 0.5);
|
||||
const y = aisleHeight + (naveHeight - aisleHeight - (windowBaseHeight + windowArchHeight)) / 2; // Center them vertically in the clerestory
|
||||
|
||||
// Left side of Nave
|
||||
createAndPlaceWindow(new THREE.Vector3(-naveWidth / 2 + 0.01, y, z), Math.PI / 2);
|
||||
// Right side of Nave
|
||||
createAndPlaceWindow(new THREE.Vector3(naveWidth / 2 - 0.01, y, z), -Math.PI / 2);
|
||||
}
|
||||
}
|
||||
|
||||
update(deltaTime) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user