@Sushant_Kumar
I found myself stuck on this topic for way to long because there is nobody answering the questions with code for how to get seamless corners and provide code for it. So for people coming to this topic searching for how to create walls with seamless corners…
These topic are helpful:
I found 2 ways:
First way i got this to work
You can do this with @hofk ThreeG.js i prefer the createProfiledContourUV over createProfiledContourMMgeometry. Because with MM each segment would handle its own normal and therefor lighting and shadow.
// Define the profile shape (thickness and height in cm, i convert all my 'units' since my points are in cm)
const thickness = 10 / 100; // Wall thickness
const height = 240 / 100; // Wall height
//create a material for each wall
const materials = [];
//example points (startpoint each wall in cm)
const points = [
{ x: 0, y: 0 },
{ x: 420, y: 0 },
{ x: 320, y: -229 },
{ x: 500, y: -330 },
{ x: 120, y: -330 }
];
//define cross-section of the wall. The wall thickness is 10cm and the height is 300cm
const profileShape = [
0, 0, // Bottom left (inner)
thickness, 0, // Bottom right (inner)
thickness, height, // Top right (inner)
0, height, // Top left (inner)
-thickness, height, // Top left (outer)
-thickness, 0 // Bottom left (outer)
];
const contour = [];
//convert my points to contour and here you can add multiple materials for each wall
points.forEach(wall => {
contour.push(wall.from.x / 100, wall.from.y / 100);
//outerwall
materials.push(new MeshPhongMaterial({
color: 0xff0000, side: DoubleSide
}))
//innerwall
materials.push(new MeshPhongMaterial({
color: 0x00ff00, side: DoubleSide
}))
//top first part
materials.push(new MeshPhongMaterial({
color: 0x0000ff, side: DoubleSide
}))
//top second part
materials.push(new MeshPhongMaterial({
color: 0x0000ff, side: DoubleSide
}))
});
const frame = new Group();
const contourClosed = true;
const openEnded = false;
const matPerSquare = false;
ThreeG.createProfiledContourUV(frame, profileShape, contour, materials, matPerSquare, contourClosed, openEnded);
frame.rotateX(-Math.PI / 2); //rotate so the frame is on the floor
frame.receiveShadow = true
frame.castShadow = true
scene.add(frame)
Second way i got this to work
Basically what you need to do is creating a wall (box) starting from one point to the next.
You will then always have a gap or intersection. You then need to calculate the vertices that intersect or leave a gap and change the vertices to the correct position. I’m still working on it and is almost finished but this gives you an idea.
Maybe someone could improve this.
//Create wall geometry with inner and outer vertices
function createWallGeometry(innerStart, innerEnd, outerStart, outerEnd) {
const geometry = new BufferGeometry();
const vertices = new Float32Array([
outerStart.x, wallHeight, outerStart.y, // outer top left
outerEnd.x, wallHeight, outerEnd.y, // outer top right
outerStart.x, 0, outerStart.y, // outer bottom left
outerEnd.x, 0, outerEnd.y, // outer bottom right
innerStart.x, wallHeight, innerStart.y, // inner top left
innerEnd.x, wallHeight, innerEnd.y, // inner top right
innerStart.x, 0, innerStart.y, // inner bottom left
innerEnd.x, 0, innerEnd.y // inner bottom right
]);
geometry.setAttribute('position', new BufferAttribute(vertices, 3));
geometry.setIndex([
0, 2, 1, 2, 3, 1, // outer face
4, 5, 6, 6, 5, 7, // inner face
0, 1, 4, 1, 5, 4, // top face
2, 6, 3, 3, 6, 7, // bottom face
0, 4, 2, 2, 4, 6, // left face
1, 3, 5, 3, 7, 5 // right face
]);
return geometry;
}
function calculateIntersection(p1, d1, p2, d2) {
const x1 = p1.x, y1 = p1.y;
const x2 = p2.x, y2 = p2.y;
const dx1 = d1.x, dy1 = d1.y;
const dx2 = d2.x, dy2 = d2.y;
const determinant = dx1 * dy2 - dy1 * dx2;
if (determinant === 0) return null; // Lines are parallel
const t = ((x2 - x1) * dy2 + (y1 - y2) * dx2) / determinant;
return { x: x1 + t * dx1, y: y1 + t * dy1 };
}
// Function to get direction vector
function getDirection(start, end) {
const length = Math.hypot(end.x - start.x, end.y - start.y);
return { x: (end.x - start.x) / length, y: (end.y - start.y) / length };
}
for (let i = 0; i < points.length; i++) {
const start = points[i];
const end = points[(i + 1) % points.length]; // Get next point point
const direction = getDirection(start, end);
const perpendicular = { x: -direction.y, y: direction.x }; // Perpendicular to direction
// Inner and outer offsets
let innerStart = {
x: start.x - perpendicular.x * wallThickness / 2,
y: start.y - perpendicular.y * wallThickness / 2
};
let innerEnd = {
x: end.x - perpendicular.x * wallThickness / 2,
y: end.y - perpendicular.y * wallThickness / 2
};
let outerStart = {
x: start.x + perpendicular.x * wallThickness / 2,
y: start.y + perpendicular.y * wallThickness / 2
};
let outerEnd = {
x: end.x + perpendicular.x * wallThickness / 2,
y: end.y + perpendicular.y * wallThickness / 2
};
if (i > 0) {
const prevStart = points[i - 1];
const prevDirection = getDirection(prevStart, start);
const prevPerpendicular = { x: -prevDirection.y, y: prevDirection.x };
let prevInnerEnd = {
x: start.x - prevPerpendicular.x * wallThickness / 2,
y: start.y - prevPerpendicular.y * wallThickness / 2
};
let prevOuterEnd = {
x: start.x + prevPerpendicular.x * wallThickness / 2,
y: start.y + prevPerpendicular.y * wallThickness / 2
};
const innerIntersection = calculateIntersection(
{ x: prevStart.x - prevPerpendicular.x * wallThickness / 2, y: prevStart.y - prevPerpendicular.y * wallThickness / 2 },
prevDirection,
innerStart,
direction
);
const outerIntersection = calculateIntersection(
{ x: prevStart.x + prevPerpendicular.x * wallThickness / 2, y: prevStart.y + prevPerpendicular.y * wallThickness / 2 },
prevDirection,
outerStart,
direction
);
if (innerIntersection) {
innerStart = innerIntersection;
prevInnerEnd = innerIntersection;
}
if (outerIntersection) {
outerStart = outerIntersection;
prevOuterEnd = outerIntersection;
}
// Update previous wall geometry with intersection points
const prevWallGeometry = createWallGeometry(prevStart, prevInnerEnd, prevStart, prevOuterEnd);
const wallMaterial = new MeshBasicMaterial({ color: 0xaa80f0, side: DoubleSide});
const prevWall = scene.children[scene.children.length - 1];
const final = mergeGeometries([prevWallGeometry, prevWall.geometry]);
const prevWallMesh = new Mesh(final, wallMaterial);
scene.add(prevWallMesh);
//remove the old wall since we now merged it
scene.remove(prevWall)
}
const wallGeometry = createWallGeometry(innerStart, innerEnd, outerStart, outerEnd);
const wallMaterial = new MeshBasicMaterial({ color: 0xfa8080, side: DoubleSide});
const wallMesh = new Mesh(wallGeometry, wallMaterial);
// Add wall to scene
scene.add(wallMesh);
}