3d tiling system?

Blitz3D Forums/Blitz3D Programming/3d tiling system?

David819(Posted 2006) [#1]
Hi, I was wandering if anyone knew how to make a 3d tiling system like the one used in the first 4 tomb raider games? Is it similar to 2d tiling? if so how would i make tiled levels etc?
thanks

edit: I would take the large guess that i would use the dim command except with three memory location decalared in it like dim(x,y,z). which aint really the hard part of this, it's more of the 3d surfaces etc that is confusing.


Matty(Posted 2006) [#2]
I would be guessing that a fairly simple method would be to have meshes of which their edges conform to a square.

These meshes would then be placed probably by your editor. The commands copymesh/addmesh would be very useful for keeping surface count down - assuming you are using a limited number of textures and sharing texture images for many of the tiles.

Having not played any of the tomb raider games I am not 100% certain as to what you want it to look like.


David819(Posted 2006) [#3]
yea, that sort of thing, well the level would be made from square tile meshes that can be deformed in the vertical sense, so say each mesh square would be of about x32*y32*z32 where the vertical hieght of the tiles may vary between 16 and 32 normally, unless it was at an angle, and if you want to go beyong 32 it creates an new 3d tile on top of the last. so a room created at the size of 12 by 4 by 8 would have x32*12 y32*4 z32*8 area. if you see what i mean. I'm going to try and make a terrain that allows me to select certain tiles of it, this should take me a while but it will be worth it if i can manage it.


WolRon(Posted 2006) [#4]
I think it would be easier to create an array of Types that stores the height of each corner of the tile as well as the x and z positions:
Type tile
  Field tilenumber
  Field x#, z#, y1#, y2#, y3#, y4#
End Type

Dim arena.tile(xtiles * ztiles)
Set the tilenumber field to equal the array offset so that you can instantly access any tile using the array offset.


David819(Posted 2006) [#5]
WolRon, i would agree, i'm going to use arrays to create the rooms aswell so give specail atribute to them as well as the tiling heights. changed my mind about using terrains due to the restriction of accepted sizes and usage. just working on a function to create a room, there's going to be quite abit of coding to it though, but it's getting there.


David819(Posted 2006) [#6]
Ok, i have complete the function to create a room, but there is a problem with the variables but i dont know what can anyone understand what the problem is. other than that i think the function should work sound.
here it is:

type room
field Name
field number
field x#,y#,z#, w#, h#, d#
field tile
field tilex#, tilez#, tiley1#, tiley2#, tiley3#, tiley4#
end type

function Create_room(room_name$,room_num#,X#,y#,Z#, width#, height#, depth#)

area.room = new room
room\name = room_name$
room\number = room_num#
room\x# = x#
room\y# = y#
room\z# = z#
room\w# = width#*32
room\h# = height#*32
room\d# = depth#*32

dim room_tiles((room\W#)/32,(room\D#)/32)

room_name$ = createmesh()
room_surf = createsurface(room_name$)

for R\x# = room\x# to room\w# step 32
for R\z# = room\z# to room\d#
totalvertexes = ((room\w#)/32) + ((room\z#)/32)
virx=(room\w#)/32
virz=(room\d#)/32
for vir = 1 to totalvertexes
vir = addvertex(room_surf, R\x#, room\y#, R\Z#)
addtriangle(room_surf,vir,vir+1,vir+virz)
addtriangle(room_surf,vir+1,vir+(virz+1),vir+virz)
next
next
next

end function


octothorpe(Posted 2006) [#7]
1. [code]
2. Dim cannot be used to declare a new array in a function
3. I'm positive that you're not creating vertices in the correct places: your "For vir" loop creates all its vertices in the same spot!
4. Entity handles are integers - no need to use a string (room_name$)
4a. Using the same variable name for two different purposes in the same function is bad for you
5. room\name is an integer?
6. The name of your variable is "area" not "room"
6a. R.room? Is it area.room, room.room, or R.room?
7. There's more, but my fingers are tired.

P.S. I'm certain that Tomb Raider didn't dynamically generate rooms. I think what you want to do is load in prebuilt meshes and paste them in where your level's 3d tile map says they should go. A room would be a room because the meshes (3d tiles) for walls and corners would be positioned around some empty tiles. I fail to see the need for vertical stretching, but that could be accomplished with an extra variable per tile and ScaleEntity(). e.g.




David819(Posted 2006) [#8]
That method seem quite good, but i can see dificulties arising there, as of creating the meshes in a 3d modeling program you cannot be 100% sure that the size 32 in say milkshape and the size 32 in blitz are the same. The only way i can see around this is to create the meshes within blitz using some of the 32 bit tile code then use a .x exporter code. but the main problem is that if you use different mesh for each part of the room, if you want a slop on one tile of the floor you would need to have individual meshes for every difference in the level which would take alot of memory. I have used the tomb raider level editors that are available and the levels seem to be edited as one whole mesh, like you could raise a tile of the floor up by the tile size without having to create an individual mesh to do so. But this is quite confusing, i'm not exactly sure of what to do to make this work well, as of when i have got the levels sorted i want to add atribute to the saved meshes to stat whether a wal is a climbable or just an ordinary one etc.
I'm going to scratch my head for a while on this, if you can think of anything please feel free to share as once i have made this (sort of TR engine), i'm going to release it in the Code archives.


David819(Posted 2006) [#9]
Ok, i have decided to go with a sort of mesh editing system, i'll make the objects like floors, walls etc in blitz and try to use a tile select thingy to place object, but i need some help with that, i dont know how to go about tile selecting in 3d, also i need to know if there is any code anywhere on extruding objects in blitz3d. Hope someone can help.

This is the working code i have got so far:

Graphics3D 640,480,32,2
SetBuffer BackBuffer()

cam=CreateCamera()
PositionEntity cam,40,50,-100

Create_room("main",0,0,0,0, 2, 0, 5)


While Not KeyHit(1)
WireFrame 0
RenderWorld

Flip
Wend
End



Function Create_room(room_name,room_num#,X#,y#,Z#, width#, height#, depth#)


x# = x#+1
y# = y#+1
z# = z#+1
w# = width#*32
h# = height#*32
d# = depth#*32



mesh = CreateMesh()
room_surf = CreateSurface(mesh)

For px# = x# To x#+w# Step 32
For pz# = z# To d# Step 32
virx=(w#)/32
virz=(d#)/32
totalvertexes = ((w#)/32 ) * ((d#)/32)
vir = AddVertex(room_surf, px#, y#, pz#)
vir2 = CreateSphere()
PositionEntity vir2,px#, y#, pz#
For vert = 0 To totalvertexes-2
AddTriangle(room_surf,vert,vert+1,vert+virz)
AddTriangle(room_surf,vert+1,vert+virz+1,vert+virz)
Next
Next
Next

End Function

I'm going to use the dim command with (x, y, z) but i need some explanation of how it works. something like psuedo-code of something like that.


David819(Posted 2006) [#10]
octothorpe Could you explain how your code works please, i dont fully understand how it works it would help alot if you could. thanks.


octothorpe(Posted 2006) [#11]
First, the program loads meshes for each of the different kinds of tiles and hides them. These meshes are loaded from (imaginary) external files. These entities need to be hidden because they'll only be used as blueprints for real tiles - real tiles will be created by cloning these blueprints. This strategy allows us to perform all the LoadMesh() operations we need to do all at once. I'm doing it for code-cleanliness here, but it's often useful to prevent slowdown in the middle of gameplay when a never-before-seen mesh needs to be spawned: if the loading was done during initialization, there's no waiting during game play.

The map is a 10x10x2 three dimensional array of tiles. The Data statements provide the information on what to fill the map with. In a real program, this data should come from external files because BASIC's Data system provides no random seeking (Restore LABEL works, but you can't use a variable for LABEL.) Also in a real program, the file would likely specify the dimensions of the map so that maps could be different sizes. Some programs might even have their maps list which meshes to use as blueprints!

There are two pieces of data which describe each map tile: tile_index and tile_rotations. tile_index tells the program which tile_mesh_blueprint to clone, while tile_rotations lets us specify how we want the tile oriented. Being able to specify how to turn the tiles means a map can use a single "corner" tile for all 4 corners of a room. As the data is read, tiles are cloned from blueprints, positioned in the correct places, and oriented as requested.

Lastly, the main program loop simply lets the user control the camera with the arrow keys.

If I left anything out or you need more detail on anything, let me know.