Saturday 31 January 2009

Depth sorting = easy when you know how

Just finished adding quick and dirty load and save routines. Just means I can place some objects, save them and it will automatically load them back in when the program starts. Anyway, the main thing I wanna talk about in this post is depth sorting. My ideal solution would have been to have each object calculate a ZOrder based on it's current position and then sort the object list and draw. Like I said, this would have been the ideal solution. Instead I've got a solution that works but is not as cut and dry as the previous method. Before I start I want to explain why this has been such a problem. Most isometric programs are tile based which means all objects occupy the same amount of space and any object that is larger than a standard tile is divided into two or more objects. What I needed for my engine was something much more versatile. Something that would accept objects of any size and any location, not just stuff that was for example 32x32x32 and ultimately only ever moved across one tile at a time. After countless experiments attempting to obtain a unique ZOrder based on the X,Y and Z and after many more tests the Width,Height and Depth also. None of this worked and despite many tutorials giving off a supposed correct formula it still didn't work in all situations so I plugged away experimenting until the solution struck me. I have no idea how many people have used this same method but it is not one that i've come across yet, however I have a feeling the ArmyOfTrolls game EdgeRetroHouse had a similar way of doing things even if the actual methods were never published. Once I'd got the method it seemed so obvious, just wish I'd thought of it sooner.

The Method - Requires that no two objects ever intersect.
If (Object1.X>=Object2.X) and (Object1.X>Object2.X+Object2.W) Then Object1InFront=True
Else
If (Object1.Y>=Object2.Y) and (Object1.Y>Object2.Y+Object2.H) Then Object1InFront=True
Else
If (Object1.Z>=Object2.Z) and (Object1.Z>Object2.Z+Object2.D) Then Object1InFront=True

Note: I have already set up a DrawList which is populated by objects that are on screen. This ensures anything offscreen is not part of the sort process. All visible objects are added to the DrawList but are not in order. The DrawList is then sorted.

Object2 is always after Object1 in the DrawList. If Object1InFront=True after our checks then we can swap their position in our DrawList. So next time round "Object1" will actually be Object 2 and vice versa and the same test will result in Object1InFront=False. I will be happy to provide some source code if there is sufficient demand.

No comments:

Post a Comment