Recalculating UV-Coordinates of CSG-Result

Hello forum!

Using csg i am creating holes for a door and a window asset in a wall.
You can see the result in this playground: https://playground.babylonjs.com/#FYR1JC#2
My next step is to apply textures on the wall, which works well for the main surfaces by applying the width and the height of the wall to uScale and vScale of the texture.
The problem is, the textures do not fit for the outer faces of the wall and the newly created faces from the csg operation.

Is there some option in csg to the UV-coordinate computation?
Or is there some way to explicitly access those uvs and positions?
How would you approach this?

P.S.: I added a FreeCamera so you can navigate with the arrow keys.

1 Like

Hi @mamu, welcome to the forum. No replies yet, huh? Sorry. You ask a good question… interesting issue. I don’t have a solve. Let’s bump to top, and listen for more ideas.

Nope :frowning:

This is a complex one as you will need to find the vertices and update their uv but how do you plan to find the vertices to update? (I have no response for this one)

Maybe csg is not what your need here :frowning:

1 Like

https://playground.babylonjs.com/#FYR1JC#15

Wingnut goofin’ around with his boxify() function. :slight_smile: It opens SOME potential for manually hacking the uvs.

There may be OTHER problems with manually-adjusting the uvs. For example, the upper left corner of the window hole… has ONE 2-value (x/y) UV. IF you change it so that the within-the-hole faces have good-looking texture-map, that will also affect the outside wall texture mapping. The uvs on that upper-left window point… are used for 2 purposes, right? Mapping the outside wall texture, AND mapping the inside-the-hole faces. (actually, 3 purposes. Outside wall, inside hole left face, and inside hole top face.)

SO… wallWithHoles would need… um… convertToFlatShadedMesh() call first… and then there would be 2-3 points (vertices) at that window corner… and thus 2-3 uvs to adjust.

https://playground.babylonjs.com/#FYR1JC#16 (convert done in line 91). After that call, the total number of verts… goes from 160 to 320, and total uvs goes from 160 to 336. The boxify() function doesn’t have a feature to show multiple points in same positions, so the box #316 at upper left window corner… might have another box or two under it. The convertToFlatShaded() call MUST add points… in order to accomplish flat-shading. It may have added points at our #316 box position (likely, it added 2 points for a total of 3 at window upper-left-outside point). (mistakes likely, I’m a noob)

IF there are multiple verts at #316 box position (probably 3), then… um… ONE of the points must have UVs set properly for outer-wall texture mapping, and another must have UVs proper for LEFT FACE of inside-the-hole texture mapping, and a third must have UVs set for TOP FACE of inside-the-hole texture mapping. Hard work (unless you are driving a modeling software package).

Alternatives? 8 small, textured planes (precisely positioned) would handle this issue, too (actually, 4 planes and 4 instances of those). Lamination. :slight_smile: These 8 “fascia planes” would give full power texturing for the inside-the-hole faces… complete freedom to make the material be something different from the rest of the wall (like a white COLOR instead of wood texture). A bit more overhead, but < 1kb added, I’d guess, and no convertToFlatShaded() needed, so you might save performance in the long run.

2 Likes

Just for fun, I created the 8 planes needed for the inside-the-holes fascia boards. They need some rotation and precision positioning yet, and my parenting failed in lines 48-51 (apparently a TypeScript thing). Still, they are sized correctly and ready for action.

https://playground.babylonjs.com/#FYR1JC#18

Good fun. (not really) :slight_smile: I suggest getting all 8 planes parented to holey wall… BEFORE any final precision positioning.

2 Likes

Update: https://playground.babylonjs.com/#FYR1JC#21 Changed it to a JS-based playground, so I could get the 8 fascia planes parented to holey-wall. Re-aranged some other stuff, too… and cloned some materials for the planes.

And then, I installed the above-the-door plane into place, uScaled/vScaled its ambientTexture to something that looks sane (lines 89-92).

It looks pretty good. Seam lines are aligning properly with textures on both sides of the wall. Slow process… but… COULD be automated within a makeTwoWindowsWall() and/or makeTwoWindowsWithDoorWall() function. It COULD be done with pure “plotting” instead of CSG, too. Gruesome.

2 Likes

I implemented a way to filter all four sides of the door (should work for the window too): https://playground.babylonjs.com/#FYR1JC#14

  1. filter the vertices inside the template using the .intersectsPoint Method
  2. remove all vertices of the front and back side using their normals as an indicator
    (at this point we have only the vertices which define the inner faces of the door)
  3. filter those vertices by their normals again

and voila you have all four sides of the door (or any other box-shaped template i guess).

Issues:

  1. Even though i extracted the vertices, i cannot update the csg mesh. The update option is not used there is guess. I scrolled through the code here. Mesh is only instantiated with new Mesh(name,scene).
  2. I need to make it rotation independent but that shouldnt be a problem as most of it is in local coordinates (we will see i will hopefully encapsulate the filtering today).

Yeah definetly :smiley: Thanks for all your input. I hope i don’t override your Versions when working further on Version #14.
So my current idea is to have windows and door templates that cut the through the wall to make space for the real windows and doors which are provided as separate meshes.

3 Likes

Here is house built using an alternative to CSG or separate planes (both perfectly good methods)
https://www.babylonjs-playground.com/#1Z71FW#45

It is from Using Build a House from a Floorplan - Babylon.js Documentation

The way is designed places the exterior texture on the frames. With some work you could set the frame texture differently.

2 Likes

~~ Quick Update ~~

I discarded the filtering solution. Problem with the filtering version was, that the front sides only looked neat because i applied a scaling on the texture (texture.uScale, texture.vScale) with the width and the height of the wall. I ran into problems when addressing the uvs in the inner sides of the door because this scaling was applied there to.

I implemented a more general solution without filtering. You can have a look at it in the playground. I iterate over every vertex and project the position of the vertex onto the plane defined by the normal of the vertex. With this solution the uv-coordinates are in metric space and the ratio (metric space -> uv space) is preserved.
I think i could also run over the uv buffer again and normalize it into a uv space that is from 0 to 1. But that is not necessary right now.

– IT IS ALL NEAT NOW :partying_face:–

(I am very happy with this solution. That was one week of work… and now it is such a small code)

Thanks JohnK for the PG. I went through the tutorial a while ago but didn’t know that there is also a solution for interior walls.

1 Like

you rock!