in 3D

Flash Player 10 Z-Sorting Class

I’m excited to announce that we now have a Z-sorting class for Flash Player 10. I had mentioned several times that I was having someone who really knows about 3D write this class. Well that person was none other than Ralph Hauwert who is one of the geniuses behind Papervision3D. You can’t get better than that!

I am hosting this class on my Google Code repository so you can download it via Subversion. For those not on SVN you can download a ZIP file of the classes. Using them is extremely easy. You simply call the SimpleZSorter.sortClips() static method and pass in the container clip that holds your 3D objects. This will need to be called repetitively inside an enter frame event if doing animation. Click on the image below to check out a simple carousel example.

For those who want to build something similar to the above example, I plan on doing a tutorial on building it tonight. Please join me in thanking Ralph for writing this for the community!

Lee

Write a Comment

Comment

58 Comments

  1. I’m so glad Ralph has finished this! I’ve been waiting for this ever since your announcement at FlashCamp.

    Thanks Lee for putting this up. Thanks Ralph for getting this out to the community!

  2. thanks Ralph

    I cant wait for the tutorial. Can you add to the project so that you can use different photos and if you click one it will enlarge?

  3. I dont get why you would even consider using this when there are the likes of Papervision3D and Away3D that can do far more advanced 3D than Flash’s native 3D.

  4. Is it just me… or is anyone else really bored of 3D now?

    No, no, wait, I’m only kidding, don’t shoot me!

    Lee, as ever, we are in your debt. Massive thanks to you, Ralph, and all the other benevolent demi-gods who share their expertise with us mortal souls. It never ceases to amaze me how generous some people can be with their time and knowledge.

    @Seb well, let’s see where it goes? I would think that something with native support is going to be simpler and less taxing on cpu/browser, plus aren’t we opening the door to hardware acceleration and all that? I’m no expert on 3D, though…

  5. @TheGreyMan Hey it’s my job to help give you the tools to do whatever you want. Is 3D getting played out? That’s not for me to decide :-) .

  6. Phew! LOL

    I’m greatly looking forward (and have been for a long time) to the Flash format becoming a viable platform for game development (instead of having to learn to speak binary, yuk) and it looks like Flash Player 10 is a significant step in that direction. Hmmm… Maybe I’ll dust off some of my old AS1/AS2 arcade homages and rework them in AS3/3D? Maybe… If only Apple would reverse their iPlainly iDiotic oversight in not supporting the Flash Player on the iPhone! What’s up with that? I mean, come on Steve!

  7. I had assumed that the flash player would show sprites with higher z values behind ones with lower z values – but I checked & it does not. That seems like an oversight ? So I’ll definitely be needing this at some point :)

  8. I am interested in seeing this example WITHOUT the zsorting. Because I was unaware that a special class was needed in order to pull something like this off. Can you post this with zsorting turned off?

  9. This is fantastic. Something that should have probably been included when they created the 3d space in flash . This makes 3d much more useful. Thank you so much Ralph.

  10. hi everyone… in paris during the presentation of the flash player 10, Thibault Imbert gave a simple sortOn method based Z axis which is intersting for simle use of 3d. With this class you give, imagine I have two clips (the same clips) at the same X,Y,Z position with one of them rotating on the Y axis for example…how will the displayObjects will be shown?
    thanks!

  11. You shouldn’t depth-sort using the Z axis, it is simple to do, and it will work for some basic display object structures (like a carousel) but will fail when you start to align (or stack) display objects along an axis. You need to depth-sort based on the distance (in global “world” 3D space) from the center of the screen (the camera) to the display object.

  12. How do you make the SimpleZSorter class work in Flex 3.2 – AIR 1.5.

    It gives an error on this : transformedMatrix.position.z

    this :
    displayObject.transform.getRelativeMatrix3D(mainParent)

    returns null

  13. i wouldn’t normally point to my implementation of something except that it’s (from my tests) a lot faster (and i had done it a while ago):
    http://blog.generalrelativity.org/?p=28

    there are a few reasons it’s substantially faster.
    1. it doesn’t need to store an Array of all the DisplayObjects.
    2. it uses the container’s transformation instead of each individual child’s as well as the presumably faster transformVectors for the transformation to global coordinates.
    3. it does a bubble sort directly on the child indices
    4. it doesn’t instantiate a value object to hold a property for sorting

    here’s my test script (prints the average over 250 frames):
    private var holder:Sprite;
    private var count:int = 0;
    private var tt:int = 0;

    public function DepthSort()
    {
    holder = new Sprite();

    addChild( holder );

    for( var i:int = 0; i 250 )
    {
    removeEventListener( Event.ENTER_FRAME, onEnterFrame );
    trace( tt / count );
    }

    }

  14. it throws an error if the container which is passed to the sortClips method
    has a child whose z property has not been explicitly set to some value before…
    within the flash ide you don’t get that error but if you run it in the debug standalone or browser plugin it says:
    TypeError: Error #1009: Der Zugriff auf eine Eigenschaft oder eine Methode eines null-Objektverweises ist nicht möglich.
    at com.theflashblog.fp10::SimpleZSorter$/sortClips()
    at Main/onEnterFrame()

    i guess it’s the same thing that “j” from comment no. 39 is talking about…

    i figured out, that if i put this (weird) line of code:
    displayObject.z = displayObject.z;

    right before this line in the sortClips method of the SimpleZSorter class:
    transformedMatrix = displayObject.transform.getRelativeMatrix3D(mainParent);

    then i can avoid that error and everything seems to be working fine.

    strange problem and a weird workaround…

    cheers
    DANILO

  15. @Danilo Sandner

    Thanks for the fix – works like a charm in FB3!

    Good work.

    Thanks to Ralph and Lee for providing it in the first place!

    Mark

  16. your demo of this looks good, but after trying it out and watching the video tut it doesn’t seem to work for my code.
    situation- I have a sprite container with 6 sprites. Each sprite is a face of a cube and I’m using the drawTriangles method to draw each face and apply textures.

    The 6 faces make up a cube so normally I use the triangle culling which works fine so long as I have a solid cube, but i wish to open the cube to see inside it, so in this case I turn off the culling, but then I get the z sorting issues which the simpleZSorter doesn’t seem able to resolve. Any ideas? I’m not using flash, just flex. (the z sorter causes a flickering of the sprites)

  17. ignore that last comment, reason it didn’t work with my code is that I’m using the drawTriangles which requires that I use Utils3D.projectVectors to project the trianlges from 3D space to 2D space so by the time I use the sortZ function everything is flat.
    I have to get the average z from each of the faces before I flatten them into 2D space and rearrange the children after that.

  18. Thanks a lot Lee and Ralph! I was wondering if anyone other than me encountered some problem regarding clips with the same z value. They tend to flicker swapping depths, the two clips switches depths continuously.

  19. Simon Altschuler: you should make a custom sort function and instead of using “sortOn” you might use “sort” and pass something like this a s the sort function:

    function compareRelativeZ(depthObjectReferenceA:DepthObjectReference, depthObjectReferenceB:DepthObjectReference):int
    {
    if(depthObjectReferenceA.relativeZ > depthObjectReferenceB.relativeZ)
    {
    return -1;
    }
    else if(depthObjectReferenceA.relativeZ < depthObjectReferenceB.relativeZ)
    {
    return 1;
    }
    else // if relativeZ is equal in both depthObjects, this avoids the flickering
    {
    var indexA:int = depthObjects.indexOf(depthObjectReferenceA.depthObject);
    var indexB:int = depthObjects.indexOf(depthObjectReferenceB.depthObject);
    var value:int;

    if(indexA < indexB)
    {
    value = -1;
    }
    else if(indexA {
    value = 1;
    }

    return value;
    }
    }

  20. Hi everyone

    i have a problem with Zsorting my buttons on my site.
    i have 5 movieclip buttons that i whant to zsort. and i still get errors anyone who can help me ?

    thax for the help

  21. Tried everything including this on a simple 3D cube, and this doesn’t work either. It’s still not sorting the faces. The problem is that it’s the cube rotating, and not the faces. The x,y and z values of the faces in the cube sprite stay the same. Still don’t understand why it does work for the image carroussel.

  22. Great stuff!

    Is it possible to only show the interior of the carousel? As to say the camera is in the center of the carousel and only shows the inner wall…

  23. Hey,

    the zSorter works fine in Flash CS4 or Flash Stand Alone Player 10, but once I embed the swf in an HTML document the z-sorting no longer works. Everything else is still ok, it’s just the z-sorting. It’s killing me. Any ideas what I’m doing wrong?

    Greetz, Toni

  24. i think that the flashplayer version in your browser is higher than the version you are compiling with. since an update of the player, it seems that the matrix3D doesn’t get initialized for every object anymore. thus the getRelativeMatrix3D()-method returns null instead of a matrix3D.

  25. Wow, totally overkill!

    Heres a quicker way:

    private function simpleZSort() : void {
    _containerToSort.sort(zSort);
    var index : uint;
    for each (var item : DisplayObject in _leaves) {
    var citem : DisplayObject = _containerToSort.getChildAt(index) as DisplayObject;
    if ( citem != item ) {
    _containerToSort.swapChildren(citem, item);
    }
    index++;
    }
    }

    private function zSort(a:DisplayObject,b:La:DisplayObject) : Number {
    return (b.z==a.z)?( (b.x==a.x)?(b.y-a.y):(b.x-a.x) ):(b.z-a.z);
    }