Interleaved tile rendering in t2dTileMap
by Neo Binedell · 07/30/2005 (3:03 pm) · 38 comments
This resource is outdated and will not be updated any further as I have started a brand new iso pack from scratch.
You can read more here
~neo
in the beginning...
One of the first things I did when I got T2D was to play with ideas for isometric tiles, etc.
I won't bore you with all the other things I tried but skip to the first (and then last) idea:
I've extended t2dTileMap and t2dTileLayer to provide built-in interleaved offsetting. I chose to do it by
deriving 2 classes nxIsoTileMap and nxIsoTileLayer from their respective T2D counterparts and only overriding
the specific methods that deal with rendering and picking of tiles. Although this could be integrated quite easily into
t2dTileLayer I preferred to do it this way as it is a lot cleaner and we don't have to keep patching the source
each time we update from cvs. It also makes it super easy to intergrate, simply drop the source files in your project
and add a lil something to the tile editor GUI and you're in the game.
If you're not too clear on what all this means lemme throw some pics at ya:
A normal grid with isometric tiles looks like this:
[note: will add images later, in the meantime enjoy the ascii version ;p]
But what we want is to offset each alternate row of tiles so it fits snugly in between the row above and the row below,
which you can fake with two overlapping layers with tiles in alternate positions:
We start as normal with row 0: X = 0, Y = 0
We tile that row as usual by adding TileWidth to X each time
For the next row, we want to interleave the tiles so we first
offset X by half a TileWidth, and we increment Y by TileHeight / 2,
then just tile the row again by adding TileWidth to X
Rinse and repeat.
Note that we ONLY offset the output coords... basically we are mapping the normal tile grid to an
interleaved output grid. Also this really has nothing to do with the isometric part of the deal
beyond allowing interleaving tiles, you can choose what view angle you want by choosing
the appropriate tile height and width ratio.
So the only render code that really had to change was the part where we incremented the output X and Y coords.
Oh yes, and the grid overlay drawing which I also changed, I wont go into the details of that just yet but I'll post
a piccy of it in the tile editor to show u what I mean as soon as I get time to put it up.
As it stands at the moment to use it you do this:
Everything else works exactly the same from there on ;p
Next I tackled the pickTile() part which is basically just mapping the world coords to the correct position on
our new interleaved grid layout which I'll wax lyrically about later.
Other things I will be tackling is of course the all important depth-sorting issues for rendering things correctly.
I plan on posting a little demo app once its ready which will hopefully help anyone trying to do isometric stuff in
T2D.
Just goes to show you can do anything in T2D ;p
For now here's some pics to give you an idea:
In the beginning:

And then there was stuff:

And he said let there be height:

Hide that pesky grid:

As you can see I've added arbitrary height to the tile renderer, which allows
you to have things like tall walls and towers, etc. This basically just lets us draw
"up" from the tile base.
Gotta love experimenting with arb stuff heheh...
update 2005-08-25:
Back from another holiday and before I get stuck in again I'll explain a bit about the tile picking.
Here's an excerpt from the comments I have in the source:
I created a little flash app to test and implement my theory and you can have a squiz at it here
Love using flash for prototyping stuff quickly and it was rather easy to integrate into C++ thereafter.
Next on my list is sorting out the artifacts I get in the editor when moving the layer, layer independent sorting, etc.
I had an idea for an lazy way to solve the depth sorting issue, i.e. don't sort at all.
Instead of drawing each layer one after another, we interleave the drawing so we draw one row from each iso layer (as well as sprite layers). This should automagically hide objects by overdraw.
After looking at the way the scenegraph works I realized that we cant really do that as each object gets asked to do its rendering and thats that. I wouldn't want to start hacking at that level just for the iso stuff though (it would be tacky ;),
so I thought perhaps create a container object that houses all the isolayers, which could then forward the render calls and split them
up per row or whatever I finally decide on. I've also started thinking that iso layers (being view dependent) might benefit from
not being derived from normal tile layers (or even scene objects) at all as we don't need to rotate them or apply physics to them,
etc. Hmmm. Perhaps an t2dISOSceneGraph ;p Let's see what my trusty code rifle brings down then ;p
Will keep you posted.
[update 2006-04-04]
I've updated the code for 1.1. but will only upload once I go over everything.
[/update]
~neo
You can read more here
~neo
One of the first things I did when I got T2D was to play with ideas for isometric tiles, etc.
I won't bore you with all the other things I tried but skip to the first (and then last) idea:
I've extended t2dTileMap and t2dTileLayer to provide built-in interleaved offsetting. I chose to do it by
deriving 2 classes nxIsoTileMap and nxIsoTileLayer from their respective T2D counterparts and only overriding
the specific methods that deal with rendering and picking of tiles. Although this could be integrated quite easily into
t2dTileLayer I preferred to do it this way as it is a lot cleaner and we don't have to keep patching the source
each time we update from cvs. It also makes it super easy to intergrate, simply drop the source files in your project
and add a lil something to the tile editor GUI and you're in the game.
If you're not too clear on what all this means lemme throw some pics at ya:
A normal grid with isometric tiles looks like this:
[note: will add images later, in the meantime enjoy the ascii version ;p]
/\/\/\/\ ___ row 0 \/\/\/\/ /\/\/\/\ ___ row 1 \/\/\/\/
But what we want is to offset each alternate row of tiles so it fits snugly in between the row above and the row below,
which you can fake with two overlapping layers with tiles in alternate positions:
/\/\/\/\ ___ row 0 \/\/\/\/\ ___ row 1 \/\/\/\/If you step through the layout of the tiles you'll find the following:
We start as normal with row 0: X = 0, Y = 0
We tile that row as usual by adding TileWidth to X each time
For the next row, we want to interleave the tiles so we first
offset X by half a TileWidth, and we increment Y by TileHeight / 2,
then just tile the row again by adding TileWidth to X
Rinse and repeat.
for( all tiles in Y )
{
if( Y % 2 ) // is this an odd row?
offsetX = TileWidth / 2
else
offsetX = 0
for( all tiles in X )
{
draw tile at XY
X += TileWidth
}
Y += TileHeight / 2
}Note that we ONLY offset the output coords... basically we are mapping the normal tile grid to an
interleaved output grid. Also this really has nothing to do with the isometric part of the deal
beyond allowing interleaving tiles, you can choose what view angle you want by choosing
the appropriate tile height and width ratio.
So the only render code that really had to change was the part where we incremented the output X and Y coords.
Oh yes, and the grid overlay drawing which I also changed, I wont go into the details of that just yet but I'll post
a piccy of it in the tile editor to show u what I mean as soon as I get time to put it up.
As it stands at the moment to use it you do this:
%map = new nxIsoTileMap(){ scenegraph = t2dScene; }
%layer = %map.createTileLayer( "16 16 32 16" );Everything else works exactly the same from there on ;p
Next I tackled the pickTile() part which is basically just mapping the world coords to the correct position on
our new interleaved grid layout which I'll wax lyrically about later.
Other things I will be tackling is of course the all important depth-sorting issues for rendering things correctly.
I plan on posting a little demo app once its ready which will hopefully help anyone trying to do isometric stuff in
T2D.
Just goes to show you can do anything in T2D ;p
For now here's some pics to give you an idea:
In the beginning:

And then there was stuff:

And he said let there be height:

Hide that pesky grid:

As you can see I've added arbitrary height to the tile renderer, which allows
you to have things like tall walls and towers, etc. This basically just lets us draw
"up" from the tile base.
Gotta love experimenting with arb stuff heheh...
update 2005-08-25:
Back from another holiday and before I get stuck in again I'll explain a bit about the tile picking.
Here's an excerpt from the comments I have in the source:
* Due to the interleaved nature of the the tessellation we cant just pick // a specific tile by using a simple formula. What we do know however is that // every alternate tile falls withing the rectangular grid. So first we pick // the rectangular grid area the point is in, then find out if it hit the actual // "diamond" in the "center" of that grid tile. If not it has to fall in one of the // four quadrants topleft,topright,bottomleft or bottomright of the diamond. We find // that by offsetting the local origin to the center of the tile and simply testing // which side of the center "diamond" edges the point falls by comparing against the // slope of that edge using one of the standard forms of the line equation: // // Y = MX + C // // where: // M = slope (Y/X) // X = X value of pick point to plug in // C = Y intercept (where line crosses Y) // // |a/\b| // |/ \| // |\ /| // |c\/d| // // So if our point fell in a we'd pick the tile to the top left of this rectangular grid tile, etc, etc.
I created a little flash app to test and implement my theory and you can have a squiz at it here
Love using flash for prototyping stuff quickly and it was rather easy to integrate into C++ thereafter.
Next on my list is sorting out the artifacts I get in the editor when moving the layer, layer independent sorting, etc.
I had an idea for an lazy way to solve the depth sorting issue, i.e. don't sort at all.
Instead of drawing each layer one after another, we interleave the drawing so we draw one row from each iso layer (as well as sprite layers). This should automagically hide objects by overdraw.
After looking at the way the scenegraph works I realized that we cant really do that as each object gets asked to do its rendering and thats that. I wouldn't want to start hacking at that level just for the iso stuff though (it would be tacky ;),
so I thought perhaps create a container object that houses all the isolayers, which could then forward the render calls and split them
up per row or whatever I finally decide on. I've also started thinking that iso layers (being view dependent) might benefit from
not being derived from normal tile layers (or even scene objects) at all as we don't need to rotate them or apply physics to them,
etc. Hmmm. Perhaps an t2dISOSceneGraph ;p Let's see what my trusty code rifle brings down then ;p
Will keep you posted.
[update 2006-04-04]
I've updated the code for 1.1. but will only upload once I go over everything.
[/update]
~neo
#2
will post stuff as soon as I can ;p
~neo
07/30/2005 (4:18 pm)
I'm doing some testing first to see if things break somewhere along the line, butwill post stuff as soon as I can ;p
~neo
#3
ok ill wait.
I give you a minute or 2! :)
07/30/2005 (4:21 pm)
I was going to go about it the same way you were.ok ill wait.
I give you a minute or 2! :)
#4
- Edo.
07/30/2005 (7:51 pm)
Just a thought. If you would reposition a 2nd layer with it's origin shift half the tilewidth for both the X and Y... wouldn't give that exactly the same result?- Edo.
#5
It just gets unwieldly tracking two layers for every "virtual" layer you want.
I initially did it that way. I changed the editor code to allow offsetting a layer and link it to another layer, etc.
However once I started piling on the layers it quickly became unmanageable and besides it didn't feel "right" to me
I'm a bit of a purist when it comes to stuff like this I suppose. ;p
This is more of a experiment for me to find the limitations (and possible improvements) for the T2D engine as
well as getting my hands dirty with the underlying code.
It starts quite simple and leads to other ideas like allowing tiles to scale outside of their cliprects in say -Y to
allow for arbitrary "heights" of walls, etc, but generalized into discreet functionality that enhances the engine.
Having a clean interface that takes care of all these things implicitely in code instead of having to fake it
in script seems to me the best way to go.
Obviously YMMV.
~neo
07/30/2005 (8:51 pm)
Yes it does, and I mentioned that as well, Quote:
which you can fake with two overlapping layers with tiles in alternate positions:
It just gets unwieldly tracking two layers for every "virtual" layer you want.
I initially did it that way. I changed the editor code to allow offsetting a layer and link it to another layer, etc.
However once I started piling on the layers it quickly became unmanageable and besides it didn't feel "right" to me
I'm a bit of a purist when it comes to stuff like this I suppose. ;p
This is more of a experiment for me to find the limitations (and possible improvements) for the T2D engine as
well as getting my hands dirty with the underlying code.
It starts quite simple and leads to other ideas like allowing tiles to scale outside of their cliprects in say -Y to
allow for arbitrary "heights" of walls, etc, but generalized into discreet functionality that enhances the engine.
Having a clean interface that takes care of all these things implicitely in code instead of having to fake it
in script seems to me the best way to go.
Obviously YMMV.
~neo
#6
07/30/2005 (11:30 pm)
Yeah I see your point and agree. For this I'd proberly prefer the axis to be turned 45 degrees so that not even/uneven rows determine the interleaved tiles but rather have a logic xy system where the tile left up would be -1X and up right would be +1Y.
#7
Btw, you've been doing some really cool stuff already. Liked your Atlas terrain GUI too. :)
07/31/2005 (12:52 pm)
Very cool Neo! We tried to make the tile system as easy to extend and modify as possible (thinking specifically about ISO tiles), but there's definitely some work involved with it. Nice job, please keep us posted!Btw, you've been doing some really cool stuff already. Liked your Atlas terrain GUI too. :)
#8
Well these are just rendering coords... nothing really to do with how you define X,Y(and Z) coords in the "virtual" map. The tile map is then mapped to and from that coord system. I do agree that accessing the map that way (basically north is top right) is more
intuitive and it is basically the "standard" way of doing things. I will play with some further ideas I have about this.
Also something else to consider re: using overlapped layers (which I forgot to mention in my previous post) is that you get overlapped pick coords for each square tile, while my solution provides correct tile picking.
@Josh:
Thanks for the kind comments ;p
08/01/2005 (12:20 pm)
@Edo: Well these are just rendering coords... nothing really to do with how you define X,Y(and Z) coords in the "virtual" map. The tile map is then mapped to and from that coord system. I do agree that accessing the map that way (basically north is top right) is more
intuitive and it is basically the "standard" way of doing things. I will play with some further ideas I have about this.
Also something else to consider re: using overlapped layers (which I forgot to mention in my previous post) is that you get overlapped pick coords for each square tile, while my solution provides correct tile picking.
@Josh:
Thanks for the kind comments ;p
#9
the tiles to hide it; should give better depth perception etc.
~neo
08/01/2005 (5:02 pm)
Hmmm... think it would be a good idea to draw the grid first so it stays at the right "depth" and allowthe tiles to hide it; should give better depth perception etc.
~neo
#10
Gotta get my Animation Datablock Tool done, so i give your iso code a try!!!!
Come on man, im like a lil kid waiting for Sponge Bob Square Pants to come on......
:)
08/01/2005 (5:07 pm)
Give it a try man!Gotta get my Animation Datablock Tool done, so i give your iso code a try!!!!
Come on man, im like a lil kid waiting for Sponge Bob Square Pants to come on......
:)
#11
~neo
08/01/2005 (5:14 pm)
Hehehe, I still have to clean up a lot of stuff etc... will let you know soon as ;p~neo
#12
Faster, faster! No food or sleep till the code is done!!!
Its sweet that some of the T2D community is helping to fill in the uncompleted areas.
Keep up the great work man!
08/01/2005 (5:23 pm)
*whip whipFaster, faster! No food or sleep till the code is done!!!
Its sweet that some of the T2D community is helping to fill in the uncompleted areas.
Keep up the great work man!
#13
08/01/2005 (10:13 pm)
@Neo Overlapped coords could also just be 'virtual'... hehe :) Anyway. It's looking good what you're doing there. It would be a nice addition to T2D and having it accessible with xyz coords and through an editor would greatly simplify things.
#14
08/03/2005 (1:21 am)
Interested in this one, only reason I would get T2D would be if it had a iso engine, its the only style of 2d game I like :)
#15
08/09/2005 (11:15 pm)
How is it going Neo? I'm willing to assist, if you need it.
#16
Back now so will update soon.
~neo
08/11/2005 (8:39 am)
Been on holiday for a bit so haven't had time yet to look at it further.Back now so will update soon.
~neo
#17
08/17/2005 (10:39 am)
Keep us updated Neo :)
#18
Will be getting back to this shortly and start sharing...
Some issues with the underlying stuff (artifacts if grid is moved, etc) I still have to tackle
as I don't want to post stuff I feel is not ready. Anyone interested though just pop me
a mail and I'll send some of the stuff I'm working on for you to take a squiz at.
~neo
08/25/2005 (11:29 am)
Pheew... back after another brief holiday ;pWill be getting back to this shortly and start sharing...
Some issues with the underlying stuff (artifacts if grid is moved, etc) I still have to tackle
as I don't want to post stuff I feel is not ready. Anyone interested though just pop me
a mail and I'll send some of the stuff I'm working on for you to take a squiz at.
~neo
#19
Do you know if there are plans on putting ISO stuff into the T2D build?
08/26/2005 (10:57 am)
Neo - I didn't see an email address for you. I'd like to take a peek even if its not totally ready. I bet others would too. Go ahead and post it as long as it builds and just give us a run down on what items are really, really busted. This can help start the feedback loop. I'm super interested in getting this working.Do you know if there are plans on putting ISO stuff into the T2D build?
#20
a big "Use at own risk and if this molests yer dog, it aint my fault, etc".
And yes youre right its always good to get people throwing ideas around when they're
all looking at the same thing.
I will package it up and post it tomorrow (Sat) when i get a chance, and ego be damned ;p
~neo
ps: are plans public and I should post a resource instead or post it in the private forums, how does it work?
08/26/2005 (11:10 am)
Hmmm... well I do believe in release soon and release often, so I'll just post the stuff witha big "Use at own risk and if this molests yer dog, it aint my fault, etc".
And yes youre right its always good to get people throwing ideas around when they're
all looking at the same thing.
I will package it up and post it tomorrow (Sat) when i get a chance, and ego be damned ;p
~neo
ps: are plans public and I should post a resource instead or post it in the private forums, how does it work?

Torque Owner Chris Newman
Im about to start some iso code myself soon, and this would give me a good start :)