remove community
This commit is contained in:
@@ -58,8 +58,12 @@ export const DoorSystem = () => {
|
||||
function addBox(
|
||||
parent: THREE.Object3D,
|
||||
material: THREE.Material,
|
||||
w: number, h: number, d: number,
|
||||
x: number, y: number, z: number,
|
||||
w: number,
|
||||
h: number,
|
||||
d: number,
|
||||
x: number,
|
||||
y: number,
|
||||
z: number,
|
||||
) {
|
||||
const m = new THREE.Mesh(new THREE.BoxGeometry(w, h, d), material)
|
||||
m.position.set(x, y, z)
|
||||
@@ -84,29 +88,77 @@ function updateDoorMesh(node: DoorNode, mesh: THREE.Mesh) {
|
||||
}
|
||||
|
||||
const {
|
||||
width, height, frameThickness, frameDepth, threshold, thresholdHeight,
|
||||
segments, handle, handleHeight, handleSide,
|
||||
doorCloser, panicBar, panicBarHeight, contentPadding, hingesSide,
|
||||
width,
|
||||
height,
|
||||
frameThickness,
|
||||
frameDepth,
|
||||
threshold,
|
||||
thresholdHeight,
|
||||
segments,
|
||||
handle,
|
||||
handleHeight,
|
||||
handleSide,
|
||||
doorCloser,
|
||||
panicBar,
|
||||
panicBarHeight,
|
||||
contentPadding,
|
||||
hingesSide,
|
||||
} = node
|
||||
|
||||
// Leaf occupies the full opening (no bottom frame bar — door opens to floor)
|
||||
const leafW = width - 2 * frameThickness
|
||||
const leafH = height - frameThickness // only top frame
|
||||
const leafH = height - frameThickness // only top frame
|
||||
const leafDepth = 0.04
|
||||
// Leaf center is shifted down from door center by half the top frame
|
||||
const leafCenterY = -frameThickness / 2
|
||||
|
||||
// ── Frame members ──
|
||||
// Left post — full height
|
||||
addBox(mesh, baseMaterial, frameThickness, height, frameDepth, -width / 2 + frameThickness / 2, 0, 0)
|
||||
addBox(
|
||||
mesh,
|
||||
baseMaterial,
|
||||
frameThickness,
|
||||
height,
|
||||
frameDepth,
|
||||
-width / 2 + frameThickness / 2,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
// Right post — full height
|
||||
addBox(mesh, baseMaterial, frameThickness, height, frameDepth, width / 2 - frameThickness / 2, 0, 0)
|
||||
addBox(
|
||||
mesh,
|
||||
baseMaterial,
|
||||
frameThickness,
|
||||
height,
|
||||
frameDepth,
|
||||
width / 2 - frameThickness / 2,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
// Head (top bar) — full width
|
||||
addBox(mesh, baseMaterial, width, frameThickness, frameDepth, 0, height / 2 - frameThickness / 2, 0)
|
||||
addBox(
|
||||
mesh,
|
||||
baseMaterial,
|
||||
width,
|
||||
frameThickness,
|
||||
frameDepth,
|
||||
0,
|
||||
height / 2 - frameThickness / 2,
|
||||
0,
|
||||
)
|
||||
|
||||
// ── Threshold (inside the frame) ──
|
||||
if (threshold) {
|
||||
addBox(mesh, baseMaterial, leafW, thresholdHeight, frameDepth, 0, -height / 2 + thresholdHeight / 2, 0)
|
||||
addBox(
|
||||
mesh,
|
||||
baseMaterial,
|
||||
leafW,
|
||||
thresholdHeight,
|
||||
frameDepth,
|
||||
0,
|
||||
-height / 2 + thresholdHeight / 2,
|
||||
0,
|
||||
)
|
||||
}
|
||||
|
||||
// ── Leaf — contentPadding border strips (no full backing; glass areas are open) ──
|
||||
@@ -142,7 +194,7 @@ function updateDoorMesh(node: DoorNode, mesh: THREE.Mesh) {
|
||||
const numCols = seg.columnRatios.length
|
||||
const colSum = seg.columnRatios.reduce((a, b) => a + b, 0)
|
||||
const usableW = contentW - (numCols - 1) * seg.dividerThickness
|
||||
const colWidths = seg.columnRatios.map(r => (r / colSum) * usableW)
|
||||
const colWidths = seg.columnRatios.map((r) => (r / colSum) * usableW)
|
||||
|
||||
// Column x-centers (relative to mesh center)
|
||||
const colXCenters: number[] = []
|
||||
@@ -157,7 +209,16 @@ function updateDoorMesh(node: DoorNode, mesh: THREE.Mesh) {
|
||||
cx = -contentW / 2
|
||||
for (let c = 0; c < numCols - 1; c++) {
|
||||
cx += colWidths[c]!
|
||||
addBox(mesh, baseMaterial, seg.dividerThickness, segH, leafDepth + 0.001, cx + seg.dividerThickness / 2, segCenterY, 0)
|
||||
addBox(
|
||||
mesh,
|
||||
baseMaterial,
|
||||
seg.dividerThickness,
|
||||
segH,
|
||||
leafDepth + 0.001,
|
||||
cx + seg.dividerThickness / 2,
|
||||
segCenterY,
|
||||
0,
|
||||
)
|
||||
cx += seg.dividerThickness
|
||||
}
|
||||
|
||||
@@ -198,9 +259,7 @@ function updateDoorMesh(node: DoorNode, mesh: THREE.Mesh) {
|
||||
const faceZ = leafDepth / 2
|
||||
|
||||
// X position: handleSide refers to which side the grip is on
|
||||
const handleX = handleSide === 'right'
|
||||
? leafW / 2 - 0.045
|
||||
: -leafW / 2 + 0.045
|
||||
const handleX = handleSide === 'right' ? leafW / 2 - 0.045 : -leafW / 2 + 0.045
|
||||
|
||||
// Backplate
|
||||
addBox(mesh, baseMaterial, 0.028, 0.14, 0.01, handleX, handleY, faceZ + 0.005)
|
||||
@@ -214,7 +273,16 @@ function updateDoorMesh(node: DoorNode, mesh: THREE.Mesh) {
|
||||
// Body
|
||||
addBox(mesh, baseMaterial, 0.28, 0.055, 0.055, 0, closerY, leafDepth / 2 + 0.03)
|
||||
// Arm (simplified as thin bar to frame side)
|
||||
addBox(mesh, baseMaterial, 0.14, 0.015, 0.015, leafW / 4, closerY + 0.025, leafDepth / 2 + 0.015)
|
||||
addBox(
|
||||
mesh,
|
||||
baseMaterial,
|
||||
0.14,
|
||||
0.015,
|
||||
0.015,
|
||||
leafW / 4,
|
||||
closerY + 0.025,
|
||||
leafDepth / 2 + 0.015,
|
||||
)
|
||||
}
|
||||
|
||||
// ── Panic bar ──
|
||||
@@ -225,9 +293,7 @@ function updateDoorMesh(node: DoorNode, mesh: THREE.Mesh) {
|
||||
|
||||
// ── Hinges (3 knuckle-style hinges on the hinge side) ──
|
||||
{
|
||||
const hingeX = hingesSide === 'right'
|
||||
? leafW / 2 - 0.012
|
||||
: -leafW / 2 + 0.012
|
||||
const hingeX = hingesSide === 'right' ? leafW / 2 - 0.012 : -leafW / 2 + 0.012
|
||||
const hingeZ = 0 // centered in leaf depth
|
||||
const hingeH = 0.1
|
||||
const hingeW = 0.024
|
||||
|
||||
@@ -74,8 +74,8 @@ function outsetPolygon(polygon: Array<[number, number]>, amount: number): Array<
|
||||
offEdges.push([polygon[i]![0], polygon[i]![1], dx, dz])
|
||||
continue
|
||||
}
|
||||
const nx = (s * dz / len) * amount
|
||||
const nz = (s * -dx / len) * amount
|
||||
const nx = ((s * dz) / len) * amount
|
||||
const nz = ((s * -dx) / len) * amount
|
||||
offEdges.push([polygon[i]![0] + nx, polygon[i]![1] + nz, dx, dz])
|
||||
}
|
||||
|
||||
|
||||
@@ -321,10 +321,10 @@ function collectCutoutBrushes(
|
||||
|
||||
// Calculate bounds in wall-local space
|
||||
const v3 = new THREE.Vector3()
|
||||
let minX = Infinity,
|
||||
maxX = -Infinity
|
||||
let minY = Infinity,
|
||||
maxY = -Infinity
|
||||
let minX = Number.POSITIVE_INFINITY,
|
||||
maxX = Number.NEGATIVE_INFINITY
|
||||
let minY = Number.POSITIVE_INFINITY,
|
||||
maxY = Number.NEGATIVE_INFINITY
|
||||
|
||||
for (let i = 0; i < positions.count; i++) {
|
||||
v3.fromBufferAttribute(positions, i)
|
||||
|
||||
@@ -58,8 +58,12 @@ export const WindowSystem = () => {
|
||||
function addBox(
|
||||
parent: THREE.Object3D,
|
||||
material: THREE.Material,
|
||||
w: number, h: number, d: number,
|
||||
x: number, y: number, z: number,
|
||||
w: number,
|
||||
h: number,
|
||||
d: number,
|
||||
x: number,
|
||||
y: number,
|
||||
z: number,
|
||||
) {
|
||||
const m = new THREE.Mesh(new THREE.BoxGeometry(w, h, d), material)
|
||||
m.position.set(x, y, z)
|
||||
@@ -84,9 +88,17 @@ function updateWindowMesh(node: WindowNode, mesh: THREE.Mesh) {
|
||||
}
|
||||
|
||||
const {
|
||||
width, height, frameDepth, frameThickness,
|
||||
columnRatios, rowRatios, columnDividerThickness, rowDividerThickness,
|
||||
sill, sillDepth, sillThickness,
|
||||
width,
|
||||
height,
|
||||
frameDepth,
|
||||
frameThickness,
|
||||
columnRatios,
|
||||
rowRatios,
|
||||
columnDividerThickness,
|
||||
rowDividerThickness,
|
||||
sill,
|
||||
sillDepth,
|
||||
sillThickness,
|
||||
} = node
|
||||
|
||||
const innerW = width - 2 * frameThickness
|
||||
@@ -94,11 +106,47 @@ function updateWindowMesh(node: WindowNode, mesh: THREE.Mesh) {
|
||||
|
||||
// ── Frame members ──
|
||||
// Top / bottom — full width
|
||||
addBox(mesh, frameMaterial, width, frameThickness, frameDepth, 0, height / 2 - frameThickness / 2, 0)
|
||||
addBox(mesh, frameMaterial, width, frameThickness, frameDepth, 0, -height / 2 + frameThickness / 2, 0)
|
||||
addBox(
|
||||
mesh,
|
||||
frameMaterial,
|
||||
width,
|
||||
frameThickness,
|
||||
frameDepth,
|
||||
0,
|
||||
height / 2 - frameThickness / 2,
|
||||
0,
|
||||
)
|
||||
addBox(
|
||||
mesh,
|
||||
frameMaterial,
|
||||
width,
|
||||
frameThickness,
|
||||
frameDepth,
|
||||
0,
|
||||
-height / 2 + frameThickness / 2,
|
||||
0,
|
||||
)
|
||||
// Left / right — inner height to avoid corner overlap
|
||||
addBox(mesh, frameMaterial, frameThickness, innerH, frameDepth, -width / 2 + frameThickness / 2, 0, 0)
|
||||
addBox(mesh, frameMaterial, frameThickness, innerH, frameDepth, width / 2 - frameThickness / 2, 0, 0)
|
||||
addBox(
|
||||
mesh,
|
||||
frameMaterial,
|
||||
frameThickness,
|
||||
innerH,
|
||||
frameDepth,
|
||||
-width / 2 + frameThickness / 2,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
addBox(
|
||||
mesh,
|
||||
frameMaterial,
|
||||
frameThickness,
|
||||
innerH,
|
||||
frameDepth,
|
||||
width / 2 - frameThickness / 2,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
|
||||
// ── Pane grid ──
|
||||
const numCols = columnRatios.length
|
||||
@@ -109,8 +157,8 @@ function updateWindowMesh(node: WindowNode, mesh: THREE.Mesh) {
|
||||
|
||||
const colSum = columnRatios.reduce((a, b) => a + b, 0)
|
||||
const rowSum = rowRatios.reduce((a, b) => a + b, 0)
|
||||
const colWidths = columnRatios.map(r => (r / colSum) * usableW)
|
||||
const rowHeights = rowRatios.map(r => (r / rowSum) * usableH)
|
||||
const colWidths = columnRatios.map((r) => (r / colSum) * usableW)
|
||||
const rowHeights = rowRatios.map((r) => (r / rowSum) * usableH)
|
||||
|
||||
// Compute column x-centers starting from left edge of inner area
|
||||
const colXCenters: number[] = []
|
||||
@@ -134,7 +182,16 @@ function updateWindowMesh(node: WindowNode, mesh: THREE.Mesh) {
|
||||
cx = -innerW / 2
|
||||
for (let c = 0; c < numCols - 1; c++) {
|
||||
cx += colWidths[c]!
|
||||
addBox(mesh, frameMaterial, columnDividerThickness, innerH, frameDepth, cx + columnDividerThickness / 2, 0, 0)
|
||||
addBox(
|
||||
mesh,
|
||||
frameMaterial,
|
||||
columnDividerThickness,
|
||||
innerH,
|
||||
frameDepth,
|
||||
cx + columnDividerThickness / 2,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
cx += columnDividerThickness
|
||||
}
|
||||
|
||||
@@ -144,7 +201,16 @@ function updateWindowMesh(node: WindowNode, mesh: THREE.Mesh) {
|
||||
cy -= rowHeights[r]!
|
||||
const divY = cy - rowDividerThickness / 2
|
||||
for (let c = 0; c < numCols; c++) {
|
||||
addBox(mesh, frameMaterial, colWidths[c]!, rowDividerThickness, frameDepth, colXCenters[c]!, divY, 0)
|
||||
addBox(
|
||||
mesh,
|
||||
frameMaterial,
|
||||
colWidths[c]!,
|
||||
rowDividerThickness,
|
||||
frameDepth,
|
||||
colXCenters[c]!,
|
||||
divY,
|
||||
0,
|
||||
)
|
||||
}
|
||||
cy -= rowDividerThickness
|
||||
}
|
||||
@@ -153,7 +219,16 @@ function updateWindowMesh(node: WindowNode, mesh: THREE.Mesh) {
|
||||
const glassDepth = Math.max(0.004, frameDepth * 0.08)
|
||||
for (let c = 0; c < numCols; c++) {
|
||||
for (let r = 0; r < numRows; r++) {
|
||||
addBox(mesh, glassMaterial, colWidths[c]!, rowHeights[r]!, glassDepth, colXCenters[c]!, rowYCenters[r]!, 0)
|
||||
addBox(
|
||||
mesh,
|
||||
glassMaterial,
|
||||
colWidths[c]!,
|
||||
rowHeights[r]!,
|
||||
glassDepth,
|
||||
colXCenters[c]!,
|
||||
rowYCenters[r]!,
|
||||
0,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,7 +237,16 @@ function updateWindowMesh(node: WindowNode, mesh: THREE.Mesh) {
|
||||
const sillW = width + sillDepth * 0.4 // slightly wider than frame
|
||||
// Protrudes from the front face of the frame (+Z)
|
||||
const sillZ = frameDepth / 2 + sillDepth / 2
|
||||
addBox(mesh, frameMaterial, sillW, sillThickness, sillDepth, 0, -height / 2 - sillThickness / 2, sillZ)
|
||||
addBox(
|
||||
mesh,
|
||||
frameMaterial,
|
||||
sillW,
|
||||
sillThickness,
|
||||
sillDepth,
|
||||
0,
|
||||
-height / 2 - sillThickness / 2,
|
||||
sillZ,
|
||||
)
|
||||
}
|
||||
|
||||
// ── Cutout (for wall CSG) — always full window dimensions, 1m deep ──
|
||||
|
||||
Reference in New Issue
Block a user