CreateCube with 6 surfaces

BlitzMax Modules Forums/MiniB3D/CreateCube with 6 surfaces

Hey, I'm having a hard time with surfaces on a simple box. -_-
I'm still really new to 3D and creating a cube seems really messy (Looking at MiniB3D code), I need some help with my own "CreateCube" function, I want one that creates a cube but with 6 surfaces instead of just one.
Any code or just simple tips would be really great, thanks!

Do you have B3D installed ? Because in the "castle" demo, there is a function that does that. Otherwise, you might want to search for the function on this site. It is called "LoadSkyBox".

Yeah cheers mate, the BirdDemo had the skybox function.
Only one problem... the textures are rotate the wrong way.

Here's my code:
Function defaultTile:TMesh(Top:Int=Null,Down:Int=Null,Left:Int=Null,Right:Int=Null)
		
	Local m:TMesh=createMesh()
	Local s:TSurface
	
	s=CreateSurface( m )
	If Top Then
		addVertex s,+1,+1,+1,0,0;addVertex s,-1,+1,+1,1,0
		AddVertex s,-1,-1,+1,1,1;AddVertex s,+1,-1,+1,0,1
		AddTriangle s,0,1,2;AddTriangle s,0,2,3
	EndIf
	
	s=CreateSurface( m )
	If Down Then
		addVertex s,-1,+1,+1,0,1;addVertex s,+1,+1,+1,0,0
		AddVertex s,+1,+1,-1,1,0;AddVertex s,-1,+1,-1,1,1
		AddTriangle s,0,1,2;AddTriangle s,0,2,3
	EndIf
	
	s=CreateSurface( m )
	If Left Then
		addVertex s,-1,+1,+1,0,0;addVertex s,-1,+1,-1,1,0
		AddVertex s,-1,-1,-1,1,1;AddVertex s,-1,-1,+1,0,1
		AddTriangle s,0,1,2;AddTriangle s,0,2,3
	EndIf
		
	s=CreateSurface( m )
	If Right Then
		addVertex s,+1,+1,-1,0,0;addVertex s,+1,+1,+1,1,0
		AddVertex s,+1,-1,+1,1,1;AddVertex s,+1,-1,-1,0,1
		AddTriangle s,0,1,2;AddTriangle s,0,2,3
	EndIf
	
	Return m
End Function


Perhaps it has something to do with uv positions?

note: [code ][/code ] (remove spaces) for code.

Heh thanks...
Yeah the UVs were messed up, after randomly trying I got the textures right.

Uh oh... still a problem...
Seems like the textures don't blend correctly on my box, the shades are visible without any texture but as soon as I apply a texture the shades disappear.
The weird thing is that if I use the same texture on a box created using the CreateBox function, the shades works perfectly fine.

Have you tried calling UpdateNormals() ?

Yeah, the shading DOES work...


But with textures applied they aren't visible :S


And the weird part is that if I use the CreateCube function and apply the same grass texture, it works perfectly fine!


The reason I'm not using the CreateCube function is because I need to be able to paint each face a different texture.
So how can I can get shades working with textures on my cube?

Maybe the difference is, that the corners of the cube contain only one vertex, but the cubes generated with defaulttile function have 3 vertices on each corner ? You could then average the normals of each vertex that shares the same corner.

Yeah that is most likely it...
Could you help me out with the code though?
I think it's really really confusing placing all the vertex and junk. -_-
The DefaultTile function is in my second post.

It could be better to find the CreateCube function from minib3d. Do you have minib3d installed ? If you go to c:\program files\blitzmax\mod, and then to sidesign.mod, minib3d.mod, then to "inc", there is a file called TMesh.bmx
In this file, there is a function called CreateCube()

Yeah as I said, I can't use that function because I need separate faces.

Well, you can copy it into your own program, and then build in the surfaces. The normals are defined in the function itself.

How would I "build in the surfaces" then?

In this function, all vertices/normals/texcoords/triangles are grouped. Each group has 4 lines, except for the "addtriangle" lines, they have 2 lines each.
You'll need to re-arrange the groups, so that 1 group of "addvertex" is followed by 1 group of "vertexnormal", 1 group of "vertextexcoords" and 1 group of "addtriangle". This will represent one surface. In total there will be 6 surfaces, each with 3x4 lines (verts) and 1x2 lines (tris).
Each surface group should be preceeded with this line:
surf:TSurface=mesh.CreateSurface()
It will create a new surface before adding vertices to it.
	Function CreateCube:TMesh(parent_ent:TEntity=Null)
	
		Local mesh:TMesh=TMesh.CreateMesh(parent_ent)
	
		Local surf:TSurface=mesh.CreateSurface()
			
		surf.AddVertex(-1.0,-1.0,-1.0)
		surf.AddVertex(-1.0, 1.0,-1.0)
		surf.AddVertex( 1.0, 1.0,-1.0)
		surf.AddVertex( 1.0,-1.0,-1.0)
		
		surf.AddVertex(-1.0,-1.0, 1.0)
		surf.AddVertex(-1.0, 1.0, 1.0)
		surf.AddVertex( 1.0, 1.0, 1.0)
		surf.AddVertex( 1.0,-1.0, 1.0)
			
		surf.AddVertex(-1.0,-1.0, 1.0)
		surf.AddVertex(-1.0, 1.0, 1.0)
		surf.AddVertex( 1.0, 1.0, 1.0)
		surf.AddVertex( 1.0,-1.0, 1.0)
		
		surf.AddVertex(-1.0,-1.0,-1.0)
		surf.AddVertex(-1.0, 1.0,-1.0)
		surf.AddVertex( 1.0, 1.0,-1.0)
		surf.AddVertex( 1.0,-1.0,-1.0)

		surf.AddVertex(-1.0,-1.0, 1.0)
		surf.AddVertex(-1.0, 1.0, 1.0)
		surf.AddVertex( 1.0, 1.0, 1.0)
		surf.AddVertex( 1.0,-1.0, 1.0)
		
		surf.AddVertex(-1.0,-1.0,-1.0)
		surf.AddVertex(-1.0, 1.0,-1.0)
		surf.AddVertex( 1.0, 1.0,-1.0)
		surf.AddVertex( 1.0,-1.0,-1.0)

		surf.VertexNormal(0,0.0,0.0,-1.0)
		surf.VertexNormal(1,0.0,0.0,-1.0)
		surf.VertexNormal(2,0.0,0.0,-1.0)
		surf.VertexNormal(3,0.0,0.0,-1.0)
	
		surf.VertexNormal(4,0.0,0.0,1.0)
		surf.VertexNormal(5,0.0,0.0,1.0)
		surf.VertexNormal(6,0.0,0.0,1.0)
		surf.VertexNormal(7,0.0,0.0,1.0)
		
		surf.VertexNormal(8,0.0,-1.0,0.0)
		surf.VertexNormal(9,0.0,1.0,0.0)
		surf.VertexNormal(10,0.0,1.0,0.0)
		surf.VertexNormal(11,0.0,-1.0,0.0)
				
		surf.VertexNormal(12,0.0,-1.0,0.0)
		surf.VertexNormal(13,0.0,1.0,0.0)
		surf.VertexNormal(14,0.0,1.0,0.0)
		surf.VertexNormal(15,0.0,-1.0,0.0)
	
		surf.VertexNormal(16,-1.0,0.0,0.0)
		surf.VertexNormal(17,-1.0,0.0,0.0)
		surf.VertexNormal(18,1.0,0.0,0.0)
		surf.VertexNormal(19,1.0,0.0,0.0)
				
		surf.VertexNormal(20,-1.0,0.0,0.0)
		surf.VertexNormal(21,-1.0,0.0,0.0)
		surf.VertexNormal(22,1.0,0.0,0.0)
		surf.VertexNormal(23,1.0,0.0,0.0)

		surf.VertexTexCoords(0,0.0,1.0)
		surf.VertexTexCoords(1,0.0,0.0)
		surf.VertexTexCoords(2,1.0,0.0)
		surf.VertexTexCoords(3,1.0,1.0)
		
		surf.VertexTexCoords(4,1.0,1.0)
		surf.VertexTexCoords(5,1.0,0.0)
		surf.VertexTexCoords(6,0.0,0.0)
		surf.VertexTexCoords(7,0.0,1.0)
		
		surf.VertexTexCoords(8,0.0,1.0)
		surf.VertexTexCoords(9,0.0,0.0)
		surf.VertexTexCoords(10,1.0,0.0)
		surf.VertexTexCoords(11,1.0,1.0)
			
		surf.VertexTexCoords(12,0.0,0.0)
		surf.VertexTexCoords(13,0.0,1.0)
		surf.VertexTexCoords(14,1.0,1.0)
		surf.VertexTexCoords(15,1.0,0.0)
	
		surf.VertexTexCoords(16,0.0,1.0)
		surf.VertexTexCoords(17,0.0,0.0)
		surf.VertexTexCoords(18,1.0,0.0)
		surf.VertexTexCoords(19,1.0,1.0)
				
		surf.VertexTexCoords(20,1.0,1.0)
		surf.VertexTexCoords(21,1.0,0.0)
		surf.VertexTexCoords(22,0.0,0.0)
		surf.VertexTexCoords(23,0.0,1.0)

		surf.VertexTexCoords(0,0.0,1.0,0.0,1)
		surf.VertexTexCoords(1,0.0,0.0,0.0,1)
		surf.VertexTexCoords(2,1.0,0.0,0.0,1)
		surf.VertexTexCoords(3,1.0,1.0,0.0,1)
		
		surf.VertexTexCoords(4,1.0,1.0,0.0,1)
		surf.VertexTexCoords(5,1.0,0.0,0.0,1)
		surf.VertexTexCoords(6,0.0,0.0,0.0,1)
		surf.VertexTexCoords(7,0.0,1.0,0.0,1)
		
		surf.VertexTexCoords(8,0.0,1.0,0.0,1)
		surf.VertexTexCoords(9,0.0,0.0,0.0,1)
		surf.VertexTexCoords(10,1.0,0.0,0.0,1)
		surf.VertexTexCoords(11,1.0,1.0,0.0,1)
			
		surf.VertexTexCoords(12,0.0,0.0,0.0,1)
		surf.VertexTexCoords(13,0.0,1.0,0.0,1)
		surf.VertexTexCoords(14,1.0,1.0,0.0,1)
		surf.VertexTexCoords(15,1.0,0.0,0.0,1)
	
		surf.VertexTexCoords(16,0.0,1.0,0.0,1)
		surf.VertexTexCoords(17,0.0,0.0,0.0,1)
		surf.VertexTexCoords(18,1.0,0.0,0.0,1)
		surf.VertexTexCoords(19,1.0,1.0,0.0,1)
				
		surf.VertexTexCoords(20,1.0,1.0,0.0,1)
		surf.VertexTexCoords(21,1.0,0.0,0.0,1)
		surf.VertexTexCoords(22,0.0,0.0,0.0,1)
		surf.VertexTexCoords(23,0.0,1.0,0.0,1)
				
		surf.AddTriangle(0,1,2) ' front
		surf.AddTriangle(0,2,3)
		surf.AddTriangle(6,5,4) ' back
		surf.AddTriangle(7,6,4)
		surf.AddTriangle(6+8,5+8,1+8) ' top
		surf.AddTriangle(2+8,6+8,1+8)
		surf.AddTriangle(0+8,4+8,7+8) ' bottom
		surf.AddTriangle(0+8,7+8,3+8)
		surf.AddTriangle(6+16,2+16,3+16) ' right
		surf.AddTriangle(7+16,6+16,3+16)
		surf.AddTriangle(0+16,1+16,5+16) ' left
		surf.AddTriangle(0+16,5+16,4+16)

		Return mesh
	
	End Function


But isn't that kind what my DefaultTile function is doing?

Exactly like in your own function, yes. The main difference would be offcourse, having the same normals and mesh buildup that CreateCube() gives. And it has 6 sides as well.

Maybe I miss something, but this is not exactly what you do in your tile function if it is still the one from above.

In your function you calculate no normals at all. You have to call m.UpdateNormals() at the end of your function. I know this was said already before, but it seems noone has recognised.

I did try putting UpdateNormals() at then end of my function but it didn't seem to do anything at all.
I merge the cubes/boxes into my "WorldModel" and the WorldModel does UpdateNormals(), that's why (I think) I don't need the UpdateNormals() in my DefaultTile function.

That makes sense then. That final UpdateNormals will overrule any existing normals. The following function will scan through all surfaces. If vertices share the same position, their normals will be averaged. It doesn't generate normals itself. However, with the optional flag, you can first perform UpdateNormals on the mesh. You could probably replace the UpdateNormals call from the WorldModel with this function.
	'example

	Import sidesign.minib3d
	
	Graphics3D 800, 600
	
	CreateLight()
	
	cam = CreateCamera()
	MoveEntity cam, 0, 0, -10
	
	cube = defaulttile()'CreateCube()
	SmoothNormals cube, True
	
	Repeat

		TurnEntity cube, 1, 2, 3
		RenderWorld()
		Flip
		
	Until KeyHit(key_escape)
	
	End


'function starts here
Type tempV
	Field x#, y#, z#
	Field nx#, ny#, nz#
	Field count#
End Type

Function SmoothNormals(mesh, generatenormals = False)

	If generatenormals Then UpdateNormals mesh

	vlist:TList = CreateList()

	For s = 1 To CountSurfaces(mesh)
	
		surf = GetSurface(mesh, s)
		
		For v = 0 To CountVertices(surf) - 1

			x# = VertexX(surf, v)		
			y# = VertexY(surf, v)
			z# = VertexZ(surf, v)
			nx# = VertexNX(surf, v)		
			ny# = VertexNY(surf, v)
			nz# = VertexNZ(surf, v)
					
			test = False
			For tv:tempV = EachIn vlist
				If (tv.x = x) And (tv.y = y) And (tv.z= z) Then
					tv.nx# = tv.nx# + nx#
					tv.ny# = tv.ny# + ny#
					tv.nz# = tv.nz# + nz#
					tv.count = tv.count + 1
					test = True
				End If
			Next
			If Not(test) Then
				tv:tempV = New tempV
				tv.x = x
				tv.y = y
				tv.z = z
				tv.nx = nx
				tv.ny = ny
				tv.nz = nz
				tv.count = 1
				ListAddLast vlist, tv
			End If
			
		Next
		
	Next

	For tv:tempV = EachIn vlist
		Print "count = " + tv.count
		Print tv.nx / tv.count
		Print tv.ny / tv.count
		Print tv.nz / tv.count
	Next

	For s = 1 To CountSurfaces(mesh)
	
		surf = GetSurface(mesh, s)
		
		For v = 0 To CountVertices(surf) - 1

			x# = VertexX(surf, v)		
			y# = VertexY(surf, v)
			z# = VertexZ(surf, v)
			
			test = False
			For tv:tempV = EachIn vlist
				If (tv.x = x) And (tv.y = y) And (tv.z= z) Then
					nx# = tv.nx#
					ny# = tv.ny#
					nz# = tv.nz#
					count# = tv.count#
					VertexNormal surf, v, nx/count, ny/count, nz/count
					test = True
				End If
			Next
			
		Next
		
	Next
	
	vlist.Clear()
		
End Function			
'ends here

Function defaultTile:TMesh(iTop=1,iDown=1,iLeft=1,iRight=1)
		
	Local m:TMesh=CreateMesh()
	Local s:TSurface
	
	s=CreateSurface( m )
	If iTop Then
		AddVertex s,+1,+1,+1,0,0;AddVertex s,-1,+1,+1,1,0
		AddVertex s,-1,-1,+1,1,1;AddVertex s,+1,-1,+1,0,1
		AddTriangle s,0,1,2;AddTriangle s,0,2,3
	EndIf
	
	s=CreateSurface( m )
	If iDown Then
		AddVertex s,-1,+1,+1,0,1;AddVertex s,+1,+1,+1,0,0
		AddVertex s,+1,+1,-1,1,0;AddVertex s,-1,+1,-1,1,1
		AddTriangle s,0,1,2;AddTriangle s,0,2,3
	EndIf
	
	s=CreateSurface( m )
	If iLeft Then
		AddVertex s,-1,+1,+1,0,0;AddVertex s,-1,+1,-1,1,0
		AddVertex s,-1,-1,-1,1,1;AddVertex s,-1,-1,+1,0,1
		AddTriangle s,0,1,2;AddTriangle s,0,2,3
	EndIf
		
	s=CreateSurface( m )
	If iRight Then
		AddVertex s,+1,+1,-1,0,0;AddVertex s,+1,+1,+1,1,0
		AddVertex s,+1,-1,+1,1,1;AddVertex s,+1,-1,-1,0,1
		AddTriangle s,0,1,2;AddTriangle s,0,2,3
	EndIf
	
	Return m
End Function


Yeah cheers Warner!!
That really worked, still some minor problems but I'll fix it sooner or later. :P
Thanks to everyone for helping me!