Triangle Placing to match grid
Blitz3D Forums/Blitz3D Programming/Triangle Placing to match grid
| ||
In attempt to save surfaces and triangles, rather than use a number of cube primitives, I wanted to construct geometry by code to form a single-surface mesh, eradicating overlaps and invisible triangles. Generally it seems as though the core concept is working, but there's some issues with the fidelity of placement: I would really apprecaite any help orsuggestions on the matter. The following code provides an executable overview of the idea and highlights the problem; ;;Identifies efficient single-surface triangleplacement for square-grid based maps. ;For this example purpose, an ARRAY data type is used, it may be more suitable to utilise banks or other data structures in actual usage. Graphics3D 1024,768,32,2 SetBuffer BackBuffer() Global SUN=CreateLight() Const WLS_TOP_BOUND=1 Const WLS_BOTTOM_BOUND=2 Const WLS_LEFT_BOUND=4 Const WLS_RIGHT_BOUND=8 Const WLS_ROOF_H=16 Const WLS_ROOF_V=32 Dim ARRAY(0,0) Dim TempArray(0,0) Type ROOFED Field X Field Y End Type SeedRnd MilliSecs() Local W=100 Local H=100 ;Example Populate Random Grid map (0 = blank, 1 = Wall) PopulateRandomMap(W,H) WaitKey() ;Now To call the Function And generate single-surface geometry Local MESH=CreateMesh() Local SURF=CreateSurface(MESH) Walls(W,H,SURF) ;EntityFX MESH,16 EntityAlpha MESH,0.5 UpdateNormals MESH DISPLAY3DOUTPUT(MESH,W,H) Function Walls(W,H,Surface,AddTop=True) W=W-1 H=H-1 Local X Local Y Dim TempArray(W,H) Local Bounds ;First Pass : Identify each grid unit boundaries. This can remove any hidden or adjoining wall faces For Y=0 To H For X=0 To W Bounds=0 If (ARRAY(X,Y)=1) Bounds=Bounds+GetTopBound(X,Y) Bounds=Bounds+GetBottomBound(X,Y,H) Bounds=Bounds+GetLeftBound(X,Y) Bounds=Bounds+GetRightBound(X,Y,W) TempArray(X,Y)=Bounds End If Next Next ;HORIZONTAL Pass : CHECK FOR CONTINUOUS HORIZONTAL WALL SEGMENTS - EACH WALL HAS A TOP (Z+1) AND BOTTOM (Z+0) FACE ALIGNED WITH X AXIS Local LengthTop Local LengthBottom Local CountingTop Local CountingBottom For Y=0 To H For X=0 To W If (TempArray(X,Y) And WLS_TOP_BOUND) LengthTop=LengthTop+1 CountingTop=True Else If (CountingTop) AddZ_PLUSGeometry(X-LengthTop,H-Y,LengthTop,Surface) LengthTop=0 CountingTop=False End If End If If (TempArray(X,Y) And WLS_BOTTOM_BOUND) LengthBottom=LengthBottom+1 CountingBottom=True Else If (CountingBottom) AddZ_MINUSGeometry(X-LengthBottom,H-Y,LengthBottom,Surface) LengthBottom=0 CountingBottom=False End If End If Next ;Break at end of row If (CountingTop) AddZ_PLUSGeometry(X-LengthTop,H-Y,LengthTop-1,Surface) LengthTop=0 CountingTop=False End If If (CountingBottom) AddZ_MINUSGeometry(X-LengthBottom,H-Y,LengthBottom-1,Surface) LengthBottom=0 CountingBottom=False End If Next ;VERTICAL Pass: CHECK FOR CONTINUOUS VERTICAL WALL SEGMENTS - EACH WALL HAS A RIGHT (X+1) AND LEFT (X+0) FACE ALIGNED WITH Z AXIS Local LengthLeft Local LengthRight Local CountingLeft Local CountingRight For X=0 To W For Y=0 To H If (TempArray(X,Y) And WLS_LEFT_BOUND) LengthLeft=LengthLeft+1 CountingLeft=True Else If (CountingLeft) AddX_MINUSGeometry(X,H-(Y-LengthLeft),LengthLeft,Surface) LengthLeft=0 CountingLeft=False End If End If If (TempArray(X,Y) And WLS_RIGHT_BOUND) LengthRight=LengthRight+1 CountingRight=True Else If (CountingRight) AddX_PLUSGeometry(X,H-(Y-LengthRight),LengthRight,Surface) LengthRight=0 CountingRight=False End If End If Next ;Break at end of row If (CountingLeft) AddX_MINUSGeometry(X,H-(Y-LengthLeft),LengthLeft-1,Surface) LengthLeft=0 CountingLeft=False End If If (CountingRight) AddZ_PLUSGeometry(X,H-(Y-LengthRight),LengthRight-1,Surface) LengthRight=0 CountingRight=False End If Next If (AddTop) ;Adds a "roof" plane geometry to the walls ;[Block] ;PLANAR PASS HORIZONTAL 1 : Determines potential rows of wall segments Local CountingHorizontal Local HorizontalLength For Y=0 To H For X=0 To W If (TempArray(X,Y) And (WLS_TOP_BOUND Or WLS_BOTTOM_BOUND)) CountingHorizontal=True HorizontalLength=HorizontalLength+1 Else If (CountingHorizontal) ProcessPlanarHorizontal(X-HorizontalLength,Y,HorizontalLength) HorizontalLength=0 CountingHorizontal=False End If End If Next ;Break at end of row If (CountingHorizontal) ProcessPlanarHorizontal(X-HorizontalLength,Y,HorizontalLength-1) HorizontalLength=0 CountingHorizontal=False End If Next ;PLANAR PASS VERTICAL 1 : Determines potential columns of wall segments Local CountingVertical Local VerticalLength For X=0 To W For Y=0 To H If (TempArray(X,Y) And (WLS_LEFT_BOUND Or WLS_RIGHT_BOUND)) CountingVertical=True VerticalLength=VerticalLength+1 Else If (CountingVertical) ProcessPlanarVertical(X,Y-VerticalLength,VerticalLength) VerticalLength=0 CountingVertical=False End If End If Next ;Break at end of row If (CountingVertical) ProcessPlanarVertical(X,Y-VerticalLength,VerticalLength-1) VerticalLength=0 CountingVertical=False End If Next ;PLANAR PASS HORIZONTAL 2 : Appliess planar roofing geometry across horizontal wall segments For Y=0 To H For X=0 To W If (TempArray(X,Y) And (WLS_ROOF_H)) CountingHorizontal=True HorizontalLength=HorizontalLength+1 Else If (CountingHorizontal) AddPLANAR_XZ_X_Geometry(X-HorizontalLength,H-Y,HorizontalLength,Surface) HorizontalLength=0 CountingHorizontal=False End If End If Next ;Break at end of row If (CountingHorizontal) AddPLANAR_XZ_X_Geometry(X-HorizontalLength,H-Y,HorizontalLength-1,Surface) HorizontalLength=0 CountingHorizontal=False End If Next ;PLANAR PASS VERTICAL 2: Appliess planar roofing geometry across horizontal wall segments For X=0 To W For Y=0 To H If (TempArray(X,Y) And (WLS_ROOF_V)) CountingVertical=True VerticalLength=VerticalLength+1 Else If (CountingVertical) AddPLANAR_XZ_Z_Geometry(X,H-(Y-VerticalLength),VerticalLength,Surface) VerticalLength=0 CountingVertical=False End If End If Next ;Break at end of row If (CountingVertical) AddPLANAR_XZ_Z_Geometry(X,H-(Y-VerticalLength),VerticalLength-1,Surface) VerticalLength=0 CountingVertical=False End If Next ;[End Block] End If Dim TempArray(0,0) End Function Function ProcessPlanarHorizontal(X,Y,Length) Local X1=X Local X2=X+Length For X=X1 To X2 TempArray(X,Y)=TempArray(X,Y) Or WLS_ROOF_H Next End Function Function ProcessPlanarVertical(X,Y,Length) Local Y1=Y Local Y2=Y+Length Local Skip For Y=Y1 To Y2 Skip=False If (TempArray(X,Y) And WLS_ROOF_H) If (Length>0) TempArray(X,Y)= (TempArray(X,Y) Xor WLS_ROOF_H) Else Skip=True End If End If If (Not(Skip)) TempArray(X,Y)=(TempArray(X,Y) Or WLS_ROOF_V) End If Next End Function Function GetTopBound(X,Y) Local Value If (Y>0) Value=(ARRAY(X,Y-1)=0) End If If (Value>1) DebugLog("GOtcha") Return Value * WLS_TOP_BOUND End Function Function GetBottomBound(X,Y,H) Local Value If (Y<H) Value=(ARRAY(X,Y+1)=0) End If If (Value>1) DebugLog("GOtcha") Return Value * WLS_BOTTOM_BOUND End Function Function GetLeftBound(X,Y) Local Value If (X>0) Value=(ARRAY(X-1,Y)=0) End If If (Value>1) DebugLog("GOtcha") Return Value * WLS_LEFT_BOUND End Function Function GetRightBound(X,Y,W) Local Value If (X<W) Value=(ARRAY(X+1,Y)=0) End If If (Value>1) DebugLog("GOtcha") Return Value * WLS_RIGHT_BOUND End Function ;GEOM Function AddPLANAR_XZ_X_Geometry(X,Z,Length,Surface) AddXZPlaneVertexPoints(X,Z,Length-1,1,Surface) Local v=CountVertices(Surface)-4 AddTriangle(Surface,v+0,v+1,v+2) AddTriangle(Surface,v+3,v+2,v+1) End Function Function AddPLANAR_XZ_Z_Geometry(X,Z,Length,Surface) AddXZPlaneVertexPoints(X,Z,1,Length-1,Surface) Local v=CountVertices(Surface)-4 AddTriangle(Surface,v+0,v+1,v+2) AddTriangle(Surface,v+3,v+2,v+1) End Function Function AddX_MINUSGeometry(X,Z,Length,Surface) AddZAxisVertexPoints(X,Z,Length,Surface) Local v=CountVertices(Surface)-4 AddTriangle(Surface,v+1,v+2,v+3) AddTriangle(Surface,v+2,v+1,v+0) End Function Function AddX_PLUSGeometry(X,Z,Length,Surface) AddZAxisVertexPoints(X+1,Z,Length,Surface) Local v=CountVertices(Surface)-4 AddTriangle(Surface,v+0,v+1,v+2) AddTriangle(Surface,v+3,v+2,v+1) End Function Function AddZ_PLUSGeometry(X,Z,Length,Surface) AddXAxisVertexPoints(X,Z,Length,Surface) Local v=CountVertices(Surface)-4 AddTriangle(Surface,v+1,v+2,v+3) AddTriangle(Surface,v+2,v+1,v+0) End Function Function AddZ_MINUSGeometry(X,Z,Length,Surface) AddXAxisVertexPoints(X+Length,Z-1,0-Length,Surface) Local v=CountVertices(Surface)-4 AddTriangle(Surface,v+1,v+2,v+3) AddTriangle(Surface,v+2,v+1,v+0) End Function Function AddXAxisVertexPoints(X#,Z#,Length,Surface) Local X1#=X# Local X2#=X#+Length AddVertex(Surface,X1#,1,Z#,1,0) AddVertex(Surface,X2#,1,Z#,0,0) AddVertex(Surface,X1#,0,Z#,1,1) AddVertex(Surface,X2#,0,Z#,0,1) End Function Function AddZAxisVertexPoints(X#,Z#,Length,Surface) Local Z1#=Z#-Length Local Z2#=Z# AddVertex(Surface,X#,1,Z1#,1,0) AddVertex(Surface,X#,1,Z2#,0,0) AddVertex(Surface,X#,0,Z1#,1,1) AddVertex(Surface,X#,0,Z2#,0,1) End Function Function AddXZPlaneVertexPoints(X#,Z#,LengthX,LengthZ,Surface) Local X1#=X# Local X2#=X#+LengthX Local Z1#=Z#-LengthZ Local Z2#=Z# AddVertex(Surface,X1#,1,Z2#,1,0) AddVertex(Surface,X2#,1,Z2#,0,0) AddVertex(Surface,X1#,1,Z1#,1,1) AddVertex(Surface,X2#,1,Z1#,0,1) End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;the following is for example purposes only Function PopulateRandomMap(W,H) ;VISUAL OUTPUT Dim ARRAY(W-1,H-1) Local Iter Local Length Local X,Y Local Dir Local RandX,RandY For Iter=1 To 100 Length=Rand(1,Sqr(H)) Dir=Rand(0,1) Select (Dir) Case 1: ;VERTICAL X=Rand(0,W-1) RandY=Rand(0,H-Length) For Y=RandY To (RandY+Length)-1 ARRAY(X,Y)=1 Next Default: ;HORIZONTAL RandX=Rand(0,W-Length) Y=Rand(0,H-1) For X=RandX To (RandX+Length)-1 ARRAY(X,Y)=1 Next End Select Next DRAWARRAYGRID(W-1,H-1) UPDATEVISUALDISPLAY End Function ;The following is just for a visual depiction of the example and are not required for use of the system Function DRAWARRAYGRID(W,H) Local X Local Y For Y= 0 To H For X=0 To W Color 0,255*ARRAY(X,Y),255 Rect X*10,Y*5,10,5,ARRAY(X,Y) Next Next End Function Function DISPLAY3DOUTPUT(Mesh,W,H) AmbientLight 128,128,128 Local Cam=CreateCamera() MoveEntity Cam,MeshWidth(Mesh)*0.5,MeshDepth(Mesh)*0.5,0-(MeshWidth(Mesh)*0.75) RotateEntity Mesh,-90,0,0,True Local Wire% = False; FlushMouse(); Local Prim=True Local PIV=CreatePivot() For x=0 To W-1 For y=0 To H-1 If ARRAY(x,y) c=CreateCube(PIV) PositionEntity c,x+0.5,((H-1)-y)-0.5,0,True ScaleMesh c,0.45,0.45,0.45 EntityAlpha c,0.5 EntityColor c,128,0,0 End If Next Next While Not KeyDown(1) Cls If (KeyHit(57)>0) Wire = Not(Wire); WireFrame ( Wire ); EndIf; If KeyHit(28) Prim=Not(Prim) If Prim ShowEntity PIV Else HideEntity PIV End If End If TranslateEntity Cam,Float(KeyDown(205)-KeyDown(203))*.1, Float(KeyDown(200)-KeyDown(208))*.1,MouseZSpeed(),1 UpdateWorld RenderWorld Color ( 255,128,000 ); Text ( 10,20,"Arrow -> move" ); Text ( 10,80,"space -> wireframe" ); Text ( 10,100,"Enter -> primitives" ); Text 0,0,TrisRendered() UPDATEVISUALDISPLAY Wend End Function Function UPDATEVISUALDISPLAY() Flip End Function |
| ||
why don't you add premade rectangle meshes (each corresponding to the side of a cube) to a surface ? apart from that i would use a similar logic than the one you use (use a 2d array to store the properties of each tile and analyze if there is (or not) a tile at front, at back, at left, at right here is the function i use to add one surface to another surface : http://www.blitzbasic.com/codearcs/codearcs.php?code=3291 |
| ||
The intent is to use the least possible triangles where possible. This means, that when a wall segment extends along, say, 5 units, I do not need 10 triangles but just two per each side. For example: Using indivdual cubes: A wall segment of 3 units comprises a total of 36 triangles: ._..._..._. |_|.|_|.|_| Current method: A wall segment of 3 units comprises just 12 triangles ._________. |_________| ________________________________________________________________________ This is detracting form the point of the discussion which is to ask for help in the position of the geometry. I suspect, ultimately, it ought to be a minor tweak to the values of Add**Geometry() functions, since otherwise, it seems to be creating the triangles with correct facing etc. |
| ||
The intent is to use the least possible triangles where possible. This means, that when a wall segment extends along, say, 5 units, I do not need 10 triangles but just two per each side. ok but you will encounter a problem (overlapping triangles) when you have tiles arranged in this way : 00100 11111 00100 |
| ||
. |
| ||
yes i took a look at your code, but i am not really in the mood to debug today. sorry good luck |
| ||
i just remembered this code by sswift, maybe it can help : http://www.blitzbasic.com/codearcs/codearcs.php?code=526 |
| ||
I am convinced the issue lies within the Add*Geometry() functions or the values passed to them. This should help in narrowing down the root of the issue. Thanks for taking the time to look at this, and I do very much appreciate your help and hope that you are feeling better :) |
| ||
one question : Do you want the walls to care about corners ? 123456 X numbers are just to identify the cells, the X is the block a the next line obviously, you can create a wall along the top of the cells from 1 to 6 But what do you expect for the bottom wall ? Does it go grom 1 to 6 ? or do you split it in 2 walls (bottom of 1, and bottom of 3 to 6) Then, just a thing : > in the function DISPLAY3DOUTPUT If ARRAY(x,y) c=CreateCube(PIV) PositionEntity c,x,y,0,True ScaleMesh c,0.9,0.9,0.9 EntityAlpha c,0.5 EntityColor c,128,0,0 If you set the position of your cubes every one unit, then your scalemesh is too large -> a cube goes from -1 to 1, so scale to 0.45 if you want it do be a bit lower than one unit. |
| ||
But what do you expect for the bottom wall ? Does it go grom 1 to 6 ? or do you split it in 2 walls (bottom of 1, and bottom of 3 to 6) As you will see if you run the example code, the walls do as I want in this regard. The top wall would run from 1 to 6 the bottom wall will be split into two: one segment at 1 (1 unit length) another from 3 to 6 (4 unit length) |
| ||
If you set the position of your cubes every one unit, then your scalemesh is too large -> a cube goes from -1 to 1, so scale to 0.45 if you want it do be a bit lower than one unit. I forgot this. Thank you. |
| ||
Updated the initial code again. 1) The RED Primitive cubes used as template are now scaled accordingly. 2) Horizontal and Vertical Wall sections are now mostly accurate. 3) Errors at the extremeties of the map are likely to be non-critical 4) Errors as result of parrallel wall segments placed adjacently will not be an issue. 5) The PLANAR "roof" seems to fail, I suspect due to situations whereby the n -> n+Length should be n-length to n and the ordering of vertices for triangle addition needs to be amended This is what needs to be looked at, and I am not proficient in 3D triangles and vertices to solve it. |
| ||
here is what I got so far. |
| ||
I think you misinterpreted the problem I have with the code. Your code sample does not solve these problems. The problem is with the accuracy of the placement of the triangles. __________ Your code sample has numerous issues of its own: 1) No roof for the walls - THE PROBLEM I HAVE IS WITH THE ROOF PLACEMENT _ SO HOW DOES IT HELP??? 2) Wall faces are rotated through Pi * radians. |
| ||
1) Hidden geometries within wall segments i.e. .___. |_|_| In your code the dividing wall is still present and unnecessary. Here, the walls are split everytime it's required. Because, I just don't understand what you're talking about, could you make a screen of what you're trying to explain (and point at the problem you're issuing if possible) ? 2) No roof for the walls Yep, I never go further until the first step is validated, I prefer having a robust base to work on :) (So I didn't implement the roof/floors yet ... and it seems I was right, I don't know where we are going) 3) Wall faces are rotated through Pi * radians. Same as previous, I don't understand what you're meaning, sorry. |
| ||
Ok, so you edited your post ... I suppose there is no problem with the walls then. THE PROBLEM I HAVE IS WITH THE ROOF PLACEMENT _ SO HOW DOES IT HELP??? I think it's time for a break if you start yelling at me for nothing ^^. So, help yourself, I'm not here to support this kind of behavior. |
| ||
Here, the walls are split everytime it's required Yep, I never go further until the first step is validated, I prefer having a robust base to work on :) (So I didn't implement the roof/floors yet ... and it seems I was right, I don't know where we are going Roofs are where I am having the most problem, if you see the most recently updated version of my code (amended in first post). Floors arent necessary* but are simply refection of the roof anyway so easy enough to add once roofs are working. Same as previous, I don't understand what you're meaning, sorry. Now that I have looked more carefully I think I understand. You have created "Rooms" and "Corridoors" - the faces of the cuboids face inwards - whereas I was intending on an external 'maze' where the walls are 'solid'. In your case the walls are visible from INSIDE, yet mine need to be visible from OUTSIDE only.* A simple FlipMesh resolved this difference. *Hopefully this distinction between inside and outside clarifies a little why the roof is important but floors arent :) |
| ||
I wasn't intending to "yell" - the caps were to highlight the importance of the roofs. Sorry. |
| ||
Ok no problem so. If the walls have to be fliped, then the roof will be really complex and need a flood fill algorithm to detect the outline and exlude inner parts. So it needs to be devided into the largest convex polygons (or at least into convex polygons ... checking the best computation case could be a total brainacke) So, it needs to start from the first "used" cell then find the next point which create the segment (always is the same orientation), anytime you have at least 3 points, you need to check if there is any empty cell in the polygon (else, the polygon is not valid) and compute again and again until all polygons are done In other words, it's an ear-clipping algorithm. *Hopefully this distinction between inside and outside clarifies a little why the roof is important but floors arent :) Actually, it probably does not change anything to the algorithm, but it certainly modify all the result. (I was thinking about an "inside" maze, which would absolutely not look like what you were doing) |
| ||
I've jsut updated the initial code again. So it needs to be devided into the largest convex polygons (or at least into convex polygons ... checking the best computation case could be a total brainacke) So, it needs to start from the first "used" cell then find the next point which create the segment (always is the same orientation), anytime you have at least 3 points, you need to check if there is any empty cell in the polygon (else, the polygon is not valid) and compute again and again until all polygons are done In other words, it's an ear-clipping algorithm. Well considering there will (in the actual implementation of this system), not be any cases other than single-unit-thick walls - remember t's an external maze, not internal corridors -, then any area considerations should be restricted to the same as the side walls... So my code simply checks along the horizontal walls and flags them for a roof, then the same for the vertical - with the caveat that if already earmarked, that section will be skipped over. Then, final passes process the data for roof in the same way as the wall creation - extending the geometry to stretch from the start of a section along its length (whether in H or V direction) This code is encapsulated between the ;[Block] and ;[End Block] lines (I use IDEal) However, there s something faulty in that regions seem to be arbitrarily skipped and this is what I cannot understand. |
| ||
Yet another small update to the initial code. It is so VERY CLOSE now to completion. The error with the roof isnow confined to SPECIFIC CASES Where: Horizontal Wall segments (i.e extending along X axis with only "TOP"(z+1) and BOTTOM(Z-1) faces) Length > 2 units The segment at Length-1 from the horizontal start of the segment is skipped- I am unsure whether to simply "kludge" a specific fix for this, or continue to try and investigate the root of the issue. |
| ||
Ignore the above. Whilst that scenario described in the post above ALWAYS produces the error, it is not the only circumstance that does so... |
| ||
If there are no "lines" wider than one cell, then it makes things way more simple. ps : I see the issue in your code but it's a bit hard to notice where it comes from, because your code is a bit hard to follow (too many recursive function calls, it does not help tracking stuff). You might want to use Vertex color and color your segment in different colors according to the place it was called from, so you should notice easier which segment is faulty. Anyway, I think you have a weird issue that is not visible -> you have segment with no length On "PLANAR PASS VERTICAL 2" : extends from 1 block the length of the segment and they will appear as single blocks (so, with a unit less, they are just empty segment) at this part of the code If (CountingVertical) ;AddPLANAR_XZ_Z_Geometry(X,H-(Y-VerticalLength),VerticalLength,Surface) AddPLANAR_XZ_Z_Geometry(X,H-(Y-VerticalLength),VerticalLength+1,Surface); Add 1 unit to the length and the blocks appear. VerticalLength=0 CountingVertical=False End If |
| ||
Adding +1 tehre only adds extra unwanted geometry. _____________ The way the counting works is that each square is assessed in sequence the algorithm doesn't "know" it needs to start or stop counting length until it encounters the required trigger value X Grid Counter 0 0 nothing 1 0 nothing 2 1 START COUNTING LENGTH=1 3 1 LENGTH=2 4 1 LENGTH=3 5 0 CEASE COUNT. CURRENT X=5 - LENGTH (3) = CORRECT START X 2 6 0 ________________________________ The only exceptions are at the end of the rows/columns, whch, in my actual project will be inaccessible boundaries which are irrelevant. This can be identified easily with: Function ProcessPlanarHorizontal(X,Y,Length) If (Length<1) Then DebugLog(X+","+Y+" "+"H Length"+Length) ;....... Function ProcessPlanarVertical(X,Y,Length) If (Length<1) Then DebugLog(X+","+Y+" "+"V Length"+Length) |
| ||
If there are no "lines" wider than one cell, then it makes things way more simple. The code you posted here works perfectly. I am looking through it now to see how to change my code. It is a little difficult because they are similar but not identical approaches. I apologise for the difficulty in readability of the code I've posted - the ACTUAL project relies on data stored in banks and is reliant on other variables so much that it was simpler to throw this example together. Thanks very much for your help in this bobysait and you make it look so easy :) |
| ||
now have fun setting u,v coords to texture it properly ;) |
| ||
now have fun setting u,v coords to texture it properly ;) __ Not an issue, no texturing is required. However given the triangles are all aligned to axes and set to unit dimensions, the normals belie the 'top','bottom','left','right' or roof facing, therefore, it is simple to then apply the UV to each accordingly. _____________________________________________________________ Well I've made some progress and have the alignment correct, the roof is done, all invisible faces have no geometry and where a longer wall intersects a shorter one, the longer one takes priority in determining the roof geometry. |
| ||
In the BuildWalls function, I forgot a small mistake (it's not a bug, but it's a totally useless check)For j = 0 To H For i = 0 To W ; this cell has a top wall If ((HAS_WALL(i,j) And 1)>0) And ((HAS_WALL(i,j) And 1)>0) ; if this wall hasn't already been built If ((WALL_FLAG(i,j) And 1) = 0) -> If ((HAS_WALL(i,j) And 1)>0) And ((HAS_WALL(i,j) And 1)>0) this is twice the same test, it's an unremoved temporary code that has not been updated. replace it with If ( ( HAS_WALL(i,j) And 1 ) > 0 ) I not "better safe than sorry" but here, a single test will do the same job as two but faster :p |
| ||
Thanks, Bobysait. I had to essentially re-write the essence of your code entirely to match the critera and conventions of my actual project (which included a more complex determination of walls than just a binary wall or no wall,as well as using banks rather than arrays) so the minor issues such as that you mention were cleared up and addressed on the way. I do appreciate your clarity though :) |