1

We trace MovieClip, frame by frame, and want to find unique objects that preset on it(this is a rasterizer flash animations for opengl). We do this work, with code below:

    public function process() : void
    {
        movieClip.addEventListener(Event.FRAME_CONSTRUCTED, onEnterFrame);
        onDone = false;

        currentFrame = 0;
        movieClip.gotoAndStop(1);

        while (!onDone)
        {
            movieClip.nextFrame();
        };
    }

    private function onEnterFrame(e:Event) : void
    {
        if ( currentFrame >= movieClip.totalFrames )
        {
            convert(movieClip);
            movieClip.removeEventListener(Event.FRAME_CONSTRUCTED, onEnterFrame);

            onDone = true;
            onDoneCallback(movieClipItem);
        }
        else
        {
            frames[currentFrame] = new Vector.<Object>();
            labels.push(movieClip.currentFrameLabel);

            for (var j:int = 0; j < movieClip.numChildren; ++j)
            {
                var child:DisplayObject = movieClip.getChildAt(j);

                if ( child.visible )
                {
                    frames[currentFrame].push(getSnapshot(child));

                    if ( !(child in objects) )
                    {
                        objects[child] = [];
                    }

                    objects[child].push(currentFrame);
                }
            }

            currentFrame++;
        };
    }

As a result we have "frames" collections where on each frame we have objects that exists on that frame. Then we try to find same objects in frame collection, and use follow function for compare objects:

private function objectEqual (left:DisplayObject, right:DisplayObject) : Boolean {
    return left === right && left.name == right.name;
}

but this compare give not good results. For example when the same movieclip added at frame 2 and at frame 10, objectEqual give us that this movie clip is different(this is different objects instance, but with the same content, so in our case thay must by equal). Also some times Shape objects may change they content, but instance and instance name will remain the same, so "objectEqual" also make mistake, and give us that "left" and "right" are same, but they different.

VC.One
  • 14,790
  • 4
  • 25
  • 57
tantra35
  • 79
  • 7
  • Regarding _objectEqual_ you could try to compare the _memory location_ of the DisplayObjects. I'm not sure if this works though but if you want to give it a try, please refer to this question's correct answer: http://stackoverflow.com/questions/1343282/how-can-i-get-an-instances-memory-location-in-actionscript – Jan Jun 30 '15 at 09:29
  • left === right, is the same, as compare memory location – tantra35 Jun 30 '15 at 10:07
  • this might not even be the right solution for your problem. When you say 'for opengl' what do you mean exactly? This is as3 runtime code so is this running with an ANE that outputs to a native opengl engine (if so this is going to be very slow) or is this running with a Stage3D engine? Here again very slow and possibly crashing app. If this is that type of case then your solution will not work. – BotMaster Jun 30 '15 at 11:13
  • we make something like this http://gafmedia.com/ – tantra35 Jun 30 '15 at 11:29
  • You can probably do with rudimentary serialization or creating a hash out of your MCs, if the compared MC's hash code is equal, count them as equal. – Vesper Jun 30 '15 at 11:38
  • @Vesper, but how to calc this hash? – tantra35 Jun 30 '15 at 11:56
  • yes that's what I mean. between gaf and what you are trying to do there's whole big difference. Doing it that way will never get you anywhere near a good performance. – BotMaster Jun 30 '15 at 12:14
  • That depends on what do you have in that display list of yours. You need to first collect all the variable and valuable data out of your display list, make sure it is in order (say you don't first query child A then child B in one case, and child B then child A in another) then serialize the resultant container (or plain call MD5, if it's a `ByteArray` already). – Vesper Jun 30 '15 at 12:35
  • PO is trying to put together a runtime solution for dealing with MovieClip with Stage3D content (or native opengl which is similar). Those engine can only accept a limited number of resource upload. That type of solution can only work with very small movies. As soon as the frame number goes up to 30 and beyond (probably even less than that) the whole system will show it's limits: parsing the movie will take time, uploading to gpu will crash the app (and uploading to gpu is a slow process). Are any of those movies more than 30 frames? What max number of frames you have? – BotMaster Jun 30 '15 at 13:58
  • @BotMaster, this code doesn't used for visualize anything, it simple extract animation matrix transformations, then we pack this into our custom format, and play it with our c++ engine – tantra35 Jun 30 '15 at 15:37
  • if you don't extract visual content then that visual content has already been extracted in some way, why not doing the same for the matrix transformations, why does it have to be at runtime. – BotMaster Jun 30 '15 at 16:02
  • anyway here's my advice to you. If there's no requirements to extract visual content and matrix transform at runtime then don't because the longer the movie the more processing time will be needed. Extracting all content (and even compare content) can be easily done with JSFL. Visual content extracted directly to spritesheet, matrix transform extracted directly to anything, json, xml, etc ... – BotMaster Jun 30 '15 at 16:08
  • For now we parse swf with as3swf and assosiate swf id with our displayObject – tantra35 Aug 25 '16 at 12:19

1 Answers1

1

like what @Vesper said, probably you should add a primitive variable (e.g. int) for each object in your frame collection and serialising the content you want to compare by a hashing function and store in that variable. As long as the hashing function provide unique output, you can just compare this variable to see if the content equal.

MasterWil
  • 891
  • 8
  • 24