A Flash Developer Resource Site

Page 1 of 2 12 LastLast
Results 1 to 20 of 30

Thread: Has anyone actually come up with perfect isometric depth sorting?

  1. #1
    (sic) Covenent's Avatar
    Join Date
    Dec 2000
    Location
    Ireland
    Posts
    709

    Has anyone actually come up with perfect isometric depth sorting?

    Ive been going back to isometrics again recently, and Ive been trying to come up with the elusive perfect depth swapping method. By perfect I mean the following that objects can move freely in 3D isometric space in units of pixels, and depth swapping is independent of tile size. My definition of isometric space is where the x-axis runs NW-SE, the z-axis runs NE-SW, and the y-axis runs N-S.

    Ive come close to it before by using a method like the following, but I dont think I ever came up with a perfect solution. This is just off the top of my head now so it might not be perfect. Note that this presumes all MovieClips that were attached to the stage where attached at the same depth level (e.g. -100) and their depth sorted isometrically immediatly.

    Code:
    function isoDepthSort (mc, isoPos) {
     mc.swapDepths((isoPos.x*103)+(isoPos.z*100)+(isoPos.y*103));
    }

  2. #2
    Senior Member Mad-Sci's Avatar
    Join Date
    Mar 2000
    Posts
    2,756
    my 2 cents:

    1. you need to track the tile you are on. This could be done by knowing the tileX,tileY, number of rows and colls etc..
    2 dupliate the tile not by usign depth+=1 rather depth+=2; so you will get tiles like 1,3,5 etc..etc..
    3.once you know the tile you are on then the hero depth=tile-1;
    or:
    if you have tiles 1 and 3 the hero will be put in between or 2.

    ms

  3. #3
    (sic) Covenent's Avatar
    Join Date
    Dec 2000
    Location
    Ireland
    Posts
    709
    Do you literally mean to duplicate the tile the hero is on, or just to get its base depth and place the hero slightly higher than it. Either way it sounds like to me that this would work where there is only possible 1 object per tile area. I actually created a few things using that above idea ages ago but it didnt seem very efficient or flexible to me.

    Thanks for the input btw.

  4. #4
    Senior Member Mad-Sci's Avatar
    Join Date
    Mar 2000
    Posts
    2,756
    no no you dont chage the tile depth, just the hero depth, and yes it works for only one object per tile, however 2 objects cannot occupy same place at the same time thus this should not be a problem.

    ms

  5. #5
    (sic) Covenent's Avatar
    Join Date
    Dec 2000
    Location
    Ireland
    Posts
    709
    Yeah thats what I thought you meant.

    But 2 or more objects can occupy the same tile as movement is allowed by pixel. Lets say each isometric tile is a grid of 16x16 squares, than there could potentially be more than 1 object on each tile if the objects grid size is smaller than that of the tile grid size (say 2x2 squares).

  6. #6
    Senior Member
    Join Date
    Jun 2000
    Posts
    896
    Hi Covenent,

    Not sure if you have my game book or not, but I developed an exact depth sorting algorithm that applies to isometric worlds. It is discussed in the chatper on isometrics.

    In MX I created an isometric class. When you use it, depth sorting is sort of built-in to it. Atttached is an example file that uses it.

    For anyone interested in just seeing the class code in MX, here it is:
    Code:
    isometricAS = function (maxx, maxz) {
    	this.maxx = maxx;
    	this.maxz = maxz;
    	this.theta = 30;
    	this.alpha = 45;
    	this.theta *= Math.PI/180;
    	this.alpha *= Math.PI/180;
    	this.sinTheta = Math.sin(this.theta);
    	this.cosTheta = Math.cos(this.theta);
    	this.sinAlpha = Math.sin(this.alpha);
    	this.cosAlpha = Math.cos(this.alpha);
    	this.leeway = 5;
    };
    isometricAS.prototype.mapToScreen = function(xpp, ypp, zpp) {
    	var yp = ypp;
    	var xp = xpp*this.cosAlpha+zpp*this.sinAlpha;
    	var zp = zpp*this.cosAlpha-xpp*this.sinAlpha;
    	var x = xp;
    	var y = yp*this.cosTheta-zp*this.sinTheta;
    	//var z = zp*this.cosTheta+yp*this.sinTheta;
    	return [x, y];
    };
    isometricAS.prototype.mapToIsoWorld = function(screenX, screenY) {
    	var z = (screenX/this.cosAlpha-screenY/(this.sinAlpha*this.sinTheta))*(1/(this.cosAlpha/this.sinAlpha+this.sinAlpha/this.cosAlpha));
    	var x = (1/this.cosAlpha)*(screenX-z*this.sinAlpha);
    	return [x, z];
    };
    isometricAS.prototype.setLeeWay = function(value) {
    	this.leeway = value;
    };
    isometricAS.prototype.calculateDepth = function(x, y, z) {
    	var x = Math.abs(x)*this.leeway;
    	var y = Math.abs(y);
    	var z = Math.abs(z)*this.leeway;
    	var a = this.maxx;
    	var b = this.maxz;
    	var floor = a*(b-1)+x;
    	var depth = a*(z-1)+x+floor*y;
    	return depth;
    };
    And here is an AS 2.0 class:
    Code:
    class isometric {
    	var maxx:Number, maxz:Number, theta:Number, alpha:Number, sinTheta:Number, cosTheta:Number, sinAlpha:Number, cosAlpha:Number;
    	var leeway:Number;
    	function isometric(x:Number, z:Number) {
    		maxx = x;
    		maxz = z;
    		theta = 30;
    		alpha = 45;
    		theta *= Math.PI/180;
    		alpha *= Math.PI/180;
    		sinTheta = Math.sin(theta);
    		cosTheta = Math.cos(theta);
    		sinAlpha = Math.sin(alpha);
    		cosAlpha = Math.cos(alpha);
    		leeway = 5;
    	}
    	function mapToScreen(xpp:Number, ypp:Number, zpp:Number):Array {
    		var yp:Number = ypp;
    		var xp:Number = xpp*cosAlpha+zpp*sinAlpha;
    		var zp:Number = zpp*cosAlpha-xpp*sinAlpha;
    		var x:Number = xp;
    		var y:Number = yp*cosTheta-zp*sinTheta;
    		return [x, y];
    	}
    	function mapToIsoWorld(screenX:Number, screenY:Number):Array {
    		var z:Number = (screenX/cosAlpha-screenY/(sinAlpha*sinTheta))*(1/(cosAlpha/sinAlpha+sinAlpha/cosAlpha));
    		var x:Number = (1/cosAlpha)*(screenX-z*sinAlpha);
    		return [x, z];
    	}
    	function setLeeway(value:Number) {
    		leeway = value;
    	}
    	function calculateDepth(x:Number, y:Number, z:Number):Number {
    		var x:Number = Math.abs(x)*leeway;
    		var y:Number = Math.abs(y);
    		var z:Number = Math.abs(z)*leeway;
    		var a:Number = maxx;
    		var b:Number = maxz;
    		var floor:Number = a*(b-1)+x;
    		var depth:Number = a*(z-1)+x+floor*y;
    		return depth;
    	}
    }

  7. #7
    ism BlinkOk's Avatar
    Join Date
    Aug 2001
    Location
    , location, location
    Posts
    5,002
    Some interesting stuff;
    http://www.geocities.com/~dr_ericlin.../indexgeo.html
    check out the "Depths sorting in isometric tiles" section.
    Last edited by BlinkOk; 10-08-2003 at 06:10 PM.
    Graphics Attract, Motion Engages, Gameplay Addicts
    XP Pro | P4 2.8Ghz | 2Gb | 80Gb,40Gb | 128Mb DDR ATI Radeon 9800 Pro

  8. #8
    (sic) Covenent's Avatar
    Join Date
    Dec 2000
    Location
    Ireland
    Posts
    709
    Ahhh excellent stuff you guys, I shall have a good old play when I get home later.

    Thank you!

  9. #9
    Senior Member tonypa's Avatar
    Join Date
    Jul 2001
    Location
    Estonia
    Posts
    8,223
    This is all very fancy and very complex.
    You can actually use easy and simple way to calculate iso depth:

    depth=x+y*width

    where x and y are objects x/y coordinates on the screen (not in iso space) and width is some high enough number like 1000.

    of course, you cant have 2 objects on exact same coordinates

  10. #10
    Heli Attack! iopred's Avatar
    Join Date
    Jun 2003
    Location
    Sydney, Australia
    Posts
    923
    tony, if you read the link posted above by Blink, you will see that that method has problems with overlaps.

  11. #11
    Senior Member tonypa's Avatar
    Join Date
    Jul 2001
    Location
    Estonia
    Posts
    8,223
    Not really, iopred, I am familiar with ericlins works and all his examples use coordinates in ISO space (rows and columns).

    If you read again what I said, you can see that I wasnt suggesting ISO space, I said screen coordinates. Beside, I have actually tested it before posting

  12. #12
    (sic) Covenent's Avatar
    Join Date
    Dec 2000
    Location
    Ireland
    Posts
    709
    I havent actually had much time to try these different methods (I only tried Ericlins quickly), so I cant rate them against each other but Tonypa's seems to work absolutely perfectly. I even tried quickly to expand it into 3 dimensions and it worked fine.

    Code:
    // _x - screen x
    // _y - screen y
    // z - iso z (axis running from the screens top to its bottom)
    this.swapDepths(this._x+this.z*500+this._y*1000);
    Im so surprised that something that simple actually works! I literally tried hundreds of simple numeric method like that ages ago, but I couldnt get any of them just right.

    Thank you guys very much!

  13. #13
    Heli Attack! iopred's Avatar
    Join Date
    Jun 2003
    Location
    Sydney, Australia
    Posts
    923
    Tony, Im an avid user of that technique, I used it AAAGES ago in an example I made for these forums, but in certain situations in Iso, it fails to do its job properly.

  14. #14
    Senior Member tonypa's Avatar
    Join Date
    Jul 2001
    Location
    Estonia
    Posts
    8,223
    Can you perhaps give an example of such situation?

  15. #15
    Heli Attack! iopred's Avatar
    Join Date
    Jun 2003
    Location
    Sydney, Australia
    Posts
    923
    Its a real old test of mine.. but it uses swapDepths(y*width+x);

    Lots of errors near the edges of the high tiles.. and a noticable difference when you move down.

  16. #16
    Junior Member
    Join Date
    Feb 2009
    Posts
    2

    Searching for the Perfect Isometric Depth Sorting

    Not sure if anyone will read this but oh well here it goes:

    Funny how this subject goes in spurts. Anyway, I am the developer for the as3isolib and have encountered a few problematic areas with my default layout algorithm for absolute positioning of isometric objects (much like Covenant, the thread's owner). For the most part, a flat map generates little or no errors, however any variable height terrain proves to be too much for the algorithm to handle.

    I based my default algorithm on the Filmation algorithm. The problem is not necessarily the algorithm itself but rather the array sort on mechanism in AS3.

    My problem is that if you rely on the low-level array.sortOn sort algorithm, not all of you objects necessarily get compared to one another. Implementing a manual sort would be performance prohibitive at best.

    So I decide to go back and try a more brute force approach to this. Namely I re-tried Tonypa's sort method modified to AS3 and for 3 dimension with variable height terrain. Did not work in certain situations. Tonypa, if you are interested in seeing examples to maybe try to refine your algorithm, I would be happy to do so.

    I also tried Jobe Makar's method outlined here and in his old game dev book. That did not work at all.

    I have seen some interesting approaches to this: One is what I will call the tile-owner approach. Basically your depths are presorted by a terrain map. Since terrain never moves, its depth can be set ahead of time and sorted as such. Then for animated content, rather than treat each animated object as a sibling of the terrain objects, it gets passed amongst the terrain objects as a child. This is still not perfect as I have seen many examples of this not ordering correctly. This also requires that bigger-than-tile-size objects to be sliced up in most cases. I know for certain the OpenSpace Engine utilizes this technique and I think Dofus might use it as well. Any thoughts on this?

    For now it seems that the perfect isometric depth sorting algorithm is still evading us. Well I wanted to throw this out here just to say my 2¢.

  17. #17
    Student
    Join Date
    Apr 2001
    Location
    -
    Posts
    4,756
    did you checked the last date this thread has been active? its been 2003 so many many many many years ago in the age of internet.

    PHP Code:
    array.sortOn("zDepth",Array.NUMERIC); 
    or
    PHP Code:
    array.sortOn("zDepth",16); 
    http://livedocs.adobe.com/flash/9.0/...=00005045.html

    always worked for me

    MasterX and I have been toying with real 3d iso- engine depth sortings but its still not perfect. I cant show my recent stuff but some of his can be seen here:
    http://board.flashkit.com/board/showthread.php?t=787321
    http://board.flashkit.com/board/showthread.php?t=786270
    http://board.flashkit.com/board/showthread.php?t=787370

    but aside from that often its quite difficult to determine the actual depth or order like here

  18. #18
    Junior Member
    Join Date
    Feb 2009
    Posts
    2
    Yeah I was aware of the original posting date. Fortunately isometric development is still in style for the Flash Player and as such, very little progress has been/can be made for improving the sorting algorithms.

    At one time I had considered doing something with 3D in an isometric perspective. Regarding primitives, you break all complex objects down into their core constituents. So a box is comprised of 6 rectangles. Then you sort those core objects using a 3D sorting algorithm and assemble the scene based on their order.

    The problem I ran into was getting all the interactive events to hook up properly.

  19. #19
    Junior Member
    Join Date
    Feb 2009
    Posts
    3

    Smile

    Quote Originally Posted by as3isolib View Post
    Yeah I was aware of the original posting date. Fortunately isometric development is still in style for the Flash Player and as such, very little progress has been/can be made for improving the sorting algorithms.

    At one time I had considered doing something with 3D in an isometric perspective. Regarding primitives, you break all complex objects down into their core constituents. So a box is comprised of 6 rectangles. Then you sort those core objects using a 3D sorting algorithm and assemble the scene based on their order.

    The problem I ran into was getting all the interactive events to hook up properly.

    I spent a lot of time last year trying to think up a good algorithm for isometric sorting. It's a bugger if what you want is a fully explorable world in all 3 directions. This is why tile-based isometric games are so popular... because you can ignore the z-sorting to a large degree; but I wanted to be able to jump, and climb, and go under things.

    I put it away in November of last year, until this January when a recent project made it relevant again. I've since come up with what I think is a reliable, fast, and foolproof way of sorting in an isometric map. The only caveat is the overlap paradox, which is avoided in the level design phase by carefully placing blocks so that the paradox is not visible. All other sorting issues have been resolved in the algorithm.

    You can check out a sample here:
    http://www.fenstalker.com/content/isoworld

    Your thoughts?

  20. #20
    Senior Member tonypa's Avatar
    Join Date
    Jul 2001
    Location
    Estonia
    Posts
    8,223
    That looks great, fenstalker

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center