Wall building in a level-editor

It looks amazing. Do you have any tricks to share?

users may want to undo/redo, and want to place windows and doors within the walls, change the colours, thickness, height, and even curve them. Sweet home 3d, which my program is based on, solves all of these problems really well.

I use an approach similar to mjurczyk’s 2nd suggestion. But I didn’t use the shape geometry or extrude. I created cube buffer geometries manually from 2d vectors with a starting and ending point. I manually calculate all angles for joins. The hard work paid off, since I was able to adapt it to make a solution for the roofing part of the application. Where the walls (now roofs) can are angled in multiple directions.


It still isn’t intuitive to use.
The most intuitive 3d modelling solution is demonstrated in Minecraft.

Yes, the own calculation of the BufferGeometry has advantages.
I did the same for frames. See Construction of frames with contour/profile

But if you change the orientation and the basic settings for scaling there, you can easily create walls. So it is a bit problematic, but it works.

Here I use indexed BufferGeometry.

The main calculation is from line 523 to 638.

The core is mathematically not that complicated.

			phi = Math.acos( e2x * e0x + e2y * e0y ) / 2;
			
			bend = Math.sign( dx0 * dy2 - dy0 * dx2 ); // z cross -> curve bending
			
			xRdiv = Math.sin( phi );
			
		}
		
		for ( let j = 0; j < rs1; j ++ ) {
			
			j3 = 3 * j;
			//.....................[    ] - 1 x is 1 right in R ...
			xR = ( gLineR.positions[ j3 ] - 1 ) * sizeFactorR;
			
			x = xc1 + xR / xRdiv * bend * ex ; 
			y = yc1 + xR / xRdiv * bend *  ey;
			z = gLineR.positions[ j3 + 1 ] * sizeFactorR * ( -1 );  //  -y LineR ->  +z FrameA
			
			vIdx = rs1 * i + j;
			
			posIdx = vIdx * 3;
			
			gFrameA.positions[ posIdx ] = x;
			gFrameA.positions[ posIdx + 1 ] = y;
			gFrameA.positions[ posIdx + 2 ] = z;
			
		}

Currently I’m working on a variant with non indexed BufferGeometry and uv’s to provide textures.

In this variant the calculation is much clearer.

ProfiledContourGeometry MultiMaterial

Will also be in the Collection of examples from discourse.threejs.org
in 2019.

Can this do these kind of merges?

Merges

With my version there are the following possibilities


The surfaces overlap and raise artifacts.

One keeps the distance corresponding to half the wall thickness. (mirrored here)

… with the other material variant.

I see. These are difficult issues to solve, and probably demand another approach if one were to merge everything.

It is not difficult, for example, if you only need these right-angled T - pieces.

Maybe this is also a possibility:
https://hofk.de/main/discourse.threejs/2019/Shapes/Shapes.html
from the Collection of examples from discourse.threejs.org

Merging wasn’t a problem I was trying to solve.

I made such for building houses in my game as well, it handles an arbitrary amount of crossings as it’s also for actual paths/roads. For roads these nodes also work as bezier anchors with additional tangents but unless you don’t need curved walls that’s not relevant :smile_cat:

The base layout is simple, you connect lines with nodes, each segment you extrude with 2 lines using a simple line intersection test for each sides adjacent segments, this way the layout also can get easily changed. Any additional info doesn’t need more than the adjacent segments, such as wall and corner normals. Additionally closed segment patches get a sorted inner (room walls) order to determine the right wall side and to iterate along the inner wall vertices.

Rooms also get sorted, this is helpful for various things, such as to determine if that room inside a room is a room or just a hole in the layout or culling.

Here’s a simple view in 2D


Or when used for simple road decals . Again the requirements for both are the same, the extrusion with the widths of the segments happens here too, as different sized paths/walls could join, and the intersections of the outer segments are needed.

You see you can end up with very steep corners, so you should work with caps which can be the following for example, you just need to handle too steep connections, for building houses i limited the angles generally, you could do it like Sims with 90 and 45 degree angles.

But if you don’t need more than 45/90 degree angles you can also work with a grid. It’s easier to implement and the result can be the same then as with segments, as you don’t have to extrude a wall for each cell, but you can join multiple walls in a row to one. With nodes you’re not limited to sizes or angles.

7 Likes

I won’t be making it that complex (or maybe if I understand it), but I’m really intrigued by this. How is the geometry calculated based on the lines/nodes? For instance, in the lower right corner on the 2D view. Must be quite complex calculating the 3D shape itself surrounding the lines.

The outer lines are already the segments used for generating the mesh, for instance just making a quad/plane along the segment with the height for the wall, each segment also knows it’s source segment (the middle line), so the top is set by the middle segment. The result is a clean mesh without any overlapping or redundant faces.

The green arrows just show wall normals and the extruded segment nodes connection order. Order is important, also to avoid building the wall quad in the wrong order so it gets backface culled.

1 Like

So, let’s say I have a corner, and the user chose to build a 45 degree wall inside that. How would you go about calculating and drawing that?
Merges

I love Sims :smile_cat: that’s why i made it to allow similar house building for my game.

corner
Like i described above it’s all based on a base layout with lines, the user draws the lines technically and the lines extrude the outline segments then.

1 Like

Yes, it’s a great game. I’m fascinated by its complexity.
Isn’t the math to do such an extrusion quite complex on a triangular mesh in order to not get any hidden faces or overlapping lines? I tried doing it in Blender for testing, but that was difficult.

Not really, but it was a bit tricky to find a general solution. I might publish the library when i have time, the simplest thing to with it is building the mesh. Maintaining the layout and the actual mesh are 2 different steps.

I’m not exactly sure how it is done in Sims exactly, it could be just based on a grid as you always are working in one and you’re limited to 2 axes + diagonal. For the mmo i’m using it for i use a raster and a few other restrictions too so people don’t get too crazy.

What you also want to avoid (especially with a different wall thickness) is edge cases where a thick wall would intersect into another wall, or 2 very steep joining walls sticking with their tip through another wall. You can either reject this or use a solution like caps, though you shouldn’t waste time thinking about union something another time, having always a wall baseline with it’s segments is managable. In my game you can also auto-lower or hide the walls where the camera is viewing inside, there needs to be a definition of what is a wall, the mesh is just a visual representation.

1 Like

It’s impressive. I don’t understand why I haven’t found more people doing it this way. Maybe it’s just too creative.

1 Like

Its not a problem I managed to solved before I gave up.

And this is how Sweet Home 3D solves it.

1 Like

Different thinkess isn’t a issue ^^ what i meant is a wall so thick, that it starts to absorb the wall of the other side of a room.