Sign in to follow this  
hellslawyer

TransformManager [AS3] & 3D-rotations in FP 10

Recommended Posts

Hi there,

 

yesterday I ran into a problem which gave me some headaches. I had a sprite that was added as a transform item to the TransformManager. Everything worked fine so far until I added a rotationY to the entire sprite. This caused the TransformManager to throw a whole bunch of errors regarding the Matrix of the sprite. After doing some debugging I realised that the Matrix of the sprite became null as soon as the rotationY property was set.

So I tried out some possible solution which all failed. Even if the rotationY property was set to 0, the errors occured. I figured out two solutions:

1. saving the properties of the sprite on selection and resetting the Matrix like this:

private function ontransformselect(e:TransformEvent):void 
{
var sp:Sprite = TransformItem(e.target).targetObject as Sprite;
if (e.type == TransformEvent.SELECT)
{
	var _x:Number = sp.x;
	var _y:Number = sp.y;
	var _scalex:Number = sp.scaleX;
	var _scaley:Number = sp.scaleY;
	var _rot:Number = sp.rotation;
	sp.transform.matrix3D = null;
	sp.x = _x;
	sp.y = _y
	sp.scaleX = _scaleX;
	sp.scaleY = _scaleY;
	sp.rotation = _rot;
}
else 
{
	sp.rotationY = -30;
}
}

Although this will work it removes the 3D-rotation of the object while it is selected what I didn't want. So I tested some other things and came up with a rather simple solution. If you wrap a container sprite around the transform object and apply the 3D-rotation to this container, the TransformManager will work just fine in 3D.

If you'd like to try it yourself, here's the code I used. It let's you choose an image from your harddrive, that is loaded into the container and mask. The masking is removed if the object is selected for transformation and reapplied afterwards.

package 
{
import com.greensock.events.TransformEvent;
import com.greensock.transform.TransformItem;
import com.greensock.transform.TransformManager;
import flash.display.Bitmap;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.FileFilter;
import flash.net.FileReference;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;

/**
 * ...
 * @author Reinhart Redel
 */
public class TransformManagerWith3DContainer extends Sprite 
{

	private var _fref:FileReference;		 	// needed to load local files

	private var _bmp:Bitmap;					// bitmap representation of loaded image

	private var _browse:Sprite;					// this is going to be the button to browse for an image

	private var _imgLoader:Loader;				// the loader for the image

	private var _manager:TransformManager;		

	private var _3DImage:Sprite;				// the root-container for the 3D-stuff
	private var _3DImagecontainer:Sprite;		// this is where the whole stuff will go
	private var _3DImagemask:Sprite;			// the mask which is applied to the 3D-Image

	private var _3DImagebounds:Sprite;			// just a helper which shows the bounds of the image after it is masked.

	private const _3D_IMG_WIDTH:Number = 300;
	private const _3D_IMG_HEIGHT:Number = 300;

	public function TransformManagerWith3DContainer():void 
	{
		if (stage) init();
		else addEventListener(Event.ADDED_TO_STAGE, init);
	}

	private function init(e:Event = null):void 
	{
		removeEventListener(Event.ADDED_TO_STAGE, init);

		_imgLoader = new Loader();

		// create and add the entire holder //

		_3DImage = new Sprite();
		_3DImage.x = _3DImage.y = 150;
		_3DImage.rotationY = -30;
		addChild(_3DImage);

		// create and add the entire image container //

		_3DImagecontainer = new Sprite();
		_3DImage.addChild(_3DImagecontainer);

		// create and add masking tho the _3DImagecontainer //

		_3DImagemask = new Sprite();
		_3DImagemask.graphics.beginFill(0,.25);
		_3DImagemask.graphics.drawRect(0, 0, _3D_IMG_WIDTH, _3D_IMG_HEIGHT);
		_3DImagemask.graphics.endFill();
		_3DImagemask.mouseEnabled = false;
		_3DImagemask.visible = false;
		_3DImage.addChild(_3DImagemask);
		_3DImagecontainer.mask = _3DImagemask;

		// create boundary box //

		_3DImagebounds = new Sprite();
		_3DImagebounds.x = _3DImagebounds.y = 150;
		_3DImagebounds.graphics.beginFill(0, 0);
		_3DImagebounds.graphics.lineStyle(1);
		_3DImagebounds.graphics.drawRect(0, 0, _3D_IMG_WIDTH, _3D_IMG_HEIGHT);
		_3DImagebounds.graphics.endFill();
		_3DImagebounds.mouseEnabled = false;
		_3DImagebounds.rotationY = -30;
		addChild(_3DImagebounds);

		// create browse button //

		_browse = new Sprite();
		_browse.graphics.lineStyle(1);
		_browse.graphics.beginFill(0xCCCCCC);
		_browse.graphics.drawRect(0, 0, 25, 25);
		_browse.graphics.endFill();
		_browse.x = 125;
		_browse.y = 150;
		_browse.buttonMode = true;
		addChild(_browse);

		// create help message //

		var tf:TextField = new TextField();
		tf.width = 200;
		tf.multiline = true;
		tf.wordWrap = true;
		tf.autoSize = TextFieldAutoSize.LEFT;

		tf.x = 550;
		tf.y = 25;
		tf.htmlText = "FlashPlayer 10 required!\n\nClick the button on the left of the rectangle to choose an image on your harddrive.\n\nClick on the image to move, scale or rotate it.\n\nClick somewhere outside of the image bounds to see how it will look like.";
		addChild(tf);

		// initiate TransformManager //

		_manager = new TransformManager();
		_manager.constrainScale = true;
		_manager.forceSelectionToFront = false;

		var tItem:TransformItem = _manager.addItem(_3DImagecontainer);
		tItem.addEventListener(TransformEvent.SELECT, ontransformselect);
		tItem.addEventListener(TransformEvent.DESELECT, ontransformselect);

		_browse.addEventListener(MouseEvent.CLICK, browsefiles);
	}

	private function ontransformselect(e:TransformEvent):void 
	{

		if (e.type == TransformEvent.SELECT)
		{
			_3DImagecontainer.mask = null;
		}
		else 
		{
			_3DImagecontainer.mask = _3DImagemask;
		}
	}

	private function browsefiles(e:MouseEvent):void 
	{
		_fref = new FileReference();
		var _fileFilter:FileFilter = new FileFilter ( "Images (JPG, GIF, PNG)", "*.jpg;*.gif;*.png;" ) ;
		_fref.browse([_fileFilter]);
		_fref.addEventListener(Event.SELECT, loadimage);
	}

	private function loadimage(e:Event):void 
	{
		_fref.removeEventListener(Event.SELECT, loadimage);
		_fref.addEventListener(Event.COMPLETE, showpreview);
		_fref.load();
	}

	private function showpreview(e:Event):void 
	{
		_fref.removeEventListener(Event.COMPLETE, showpreview);
		_imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, resizeloader);
		_imgLoader.loadBytes(_fref.data);
	}

	private function resizeloader(e:Event):void 
	{
		_imgLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, resizeloader);
		if (_bmp)
		{
			_bmp.bitmapData.dispose();
			_3DImagecontainer.removeChild(_bmp);
			_3DImagecontainer.x = _3DImagecontainer.y = _3DImagecontainer.rotation = 0;
			_3DImagecontainer.scaleX = _3DImagecontainer.scaleY = 1;
		}
		_bmp = Bitmap(e.target.content);
		_bmp.smoothing = true;
		_imgLoader.unload();

		_bmp.width = _3D_IMG_WIDTH;
		_bmp.scaleY = _bmp.scaleX;
		if (_bmp.height > _3D_IMG_HEIGHT)
		{
			_bmp.height = _3D_IMG_HEIGHT;
			_bmp.scaleX = _bmp.scaleY;

		}			
		_3DImagecontainer.addChild(_bmp);
	}

}

}

Hope this helps someone who runs into the same problem.

 

Cheers

Reinhart

Share this post


Link to post
Share on other sites

Hi there,

 

after some tests with the latest version of the TransformManager, I noticed, that my workaround doesn't work any more. But there's of course a simple fix for it. All you need to do is add another container to the displaylist to make it work again, because the TransformManager tries to get the transformation matrix of the parent, which actually is the 3D container and therefore this returns null.

So here's the fix:

// create and add the entire image container //
        _var _dummybox:Sprite = new Sprite();
        _3DImage.addChild(_dummybox);         
        _3DImagecontainer = new Sprite();
        _dummybox.addChild(_3DImagecontainer);

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.