Posts Tagged ‘bug’

Fixing Twease – tweaxing

January 24th, 2011

Yup, I know that everyone’s using TweenLite or Tween-something from GreenSock, but some time ago TweenLite wasn’t free for commercial use so I had to grab something different. I’ve found Twease – nice’n’small tweening lib with bezier tweening and several other fancy options. Then I’ve used to it, and it appeared in various projects. But there is annoying bug – Twease (newest version, 2.0) doesn’t render tween if your computer slowed down during the time the tween was taking place.
Imagine – you are building an app which initializes thousands of different stuff at the beginning and animates an alpha component of DisplayObject’s, so that they could appear after launching your app. But they won’t appear if somebody has 300Mhz Athlon or 1000 tabs opened in firefox.
Debugging a tweening classes is quite unpleasant, due to asynchronousity and hundreds of anonumous classes with strange short names and properties (yup, I think that majority of Tweening libraries are written in this hard-to-read way ;) ), so I never fixed this but used different hacks… until now. Jeez… the fix is simple and I could do this two years ago, but I wanted to write a pile of workarounds rather than to look into Twease’s code.

Ok, so finally, this is the fix –

1. You get rid of the “import flash.utils.getTimer;” at the beginning
2. You define some global vars

private static var frameCounter:uint = 0;
// 1000 miliseconds / 50 frames per second = 20ms for displaying one frame
private static var _ms:Number = 1000/50;

3. you write your own getTimer function

private static function getTimer():uint{
    return frameCounter*_ms;
}

4. at the beginning of an “update” function you increment “frameCounter”:

public static function update(timerevent:Event):void {
    frameCounter++;
    (...)

5. And to add a pinch of a spice to our masterpiece, we add setter and getter of “_ms” variable:

public static function set fps( val:Number ):void{
    _ms = 1000/val
}
public static function get fps( ):Number{
    return 1000/_ms;
}

What we do here, we change Twease’s getTimer() method which gets time since flash vm start, to quasi-getTimer which returns the same, but with respect to frame-drops – so if we will loose some frames during tweening, our getTimer will slow down too. This is rather a hack than a bug fix – a real fix would involve changing something in Twease’s “render” function, to force rendering of the tween at the end.
At the beginning we should provide our movie’s frameRate:

Twease.fps = stage.frameRate;

Otherwise we assume that the framerate is 50. Ok, Im talkin obvious things right now so this is the end of this post. (“hacked” twease: here)

Tags: , , ,
Posted in flash experiments | Comments (0)

Very “efficient” DAE parser in papervision 3d

January 22nd, 2009

I’m currently workin on some bigger project, and I needed to load DAE file. It’s known, that papervision3d has DAE parser – so I used it. But when I tried to load a little bigger file ( only 400KB model ), flash thrown 15 seconds timeout exception. The exception was thrown during unpack process. “Wow, flash is so slow, that it can’t unpack 400KB zip in 15 seconds? This sucks” I thought. But later I looked deeper into DAE parser’s code. DAE parser uses KMZ parser, to unpack DAE’s content ( like textures and models ), and then parses XML ( or rather KMZ unpacks and then uses DAE to read model… ). I followed the code ( just like Dexter does ), and studied KMZ parser’s code. And it appears, that KMZ’s parser code, isn’t the most efficient code I’ve ever seen.

Just look @ it:

http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/parsers/KMZ.as

After loading the zip file, it calls “parse” function, which calls “getColladaFromZip”. getColladaFromZip unopacks the zip file:

private function getColladaFromZip( zipFile : ZipFile ) : ByteArray  {
	for(var i:int = 0; i < zipFile.entries.length; i++) {
	    var entry:ZipEntry = zipFile.entries[i];

	    // extract the entry's data from the zip
	    var data:ByteArray = zipFile.getInput(entry);

		if(entry.name.toLowerCase().indexOf(".dae") != -1) {
			return data;
		}
	}
	return null;
}

It unpacks entire file, just to get the “dae” file, and then returns. More – it extracts content ( function “getInput” ) , and then checks if unpacked content is “dae” file, despite the fact, that to check it, we don’t need to unpack anything to check it.

It gets worse later – it unpacks entire file to check how many textures we have in the zip:

private function numTexturesInZip( zipFile : ZipFile ) : uint {
	var count : uint = 0;
	for(var i:int = 0; i < zipFile.entries.length; i++) {
	    var entry:ZipEntry = zipFile.entries[i];

	    // extract the entry's data from the zip
	    var data:ByteArray = zipFile.getInput(entry);

	    if(entry.name.toLowerCase().indexOf(".png") != -1 || entry.name.toLowerCase().indexOf(".jpg") != -1) {
		count++;
	 }
	 }
	return count;
}

Ok, and at the end, in the “parse” function, every file in archive is extracted again, only for purpose of loading textures from this archive.

Reassuming, if you have 1 meg model and several 200 KB textures, KMZ parser extracts geometry 3 times – second time, to count number of textures (?!?) and third, to load textures. Every texture is extrated 3 times too – first time – to ensure that the texture isn’t a model, second – to count it, and finally third time – to load texture. I think that somebody pasted the code of loading zip file from some tutorial and repasted it 3 times :)

I would paste here my code of better KMZ parser, but it’s too integrated with my project, so you’ll have to wait ; p

And I wrote this post, to enlight you people, that when you are using pv3d’s KMZ parser to load zipped DAE, it isn’t the best parser to use.

Tags: , , , , , ,
Posted in flash experiments | Comments (10)