////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package org.apache.flex.core
{
	import org.apache.flex.events.Event;
	import org.apache.flex.events.EventDispatcher;

    /**
     *  The SimpleCSSStyles class contains CSS style
     *  properties supported by SimpleCSSValuesImpl.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.2
     *  @playerversion AIR 2.6
     *  @productversion FlexJS 0.0
     */
	public class SimpleCSSStyles
	{
        /**
         *  Constructor.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function SimpleCSSStyles()
		{
			super();
		}

		private var _object:IStyleableObject;

        /**
         *  The object to which these styles apply.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function get object():IStyleableObject
		{
			return _object;
		}

        /**
         *  @private
         */
		public function set object(value:IStyleableObject):void
		{
			if (_object != value)
			{
                _object = value;
			}
		}

        public var top:*;
        public var bottom:*;
        public var left:*;
        public var right:*;
        public var padding:*;
		public var paddingLeft:*;
        public var paddingRight:*;
        public var paddingTop:*;
        public var paddingBottom:*;
        public var horizontalCenter:*;
        public var verticalCenter:*;
        public var horizontalAlign:*;
        public var verticalAlign:*;
        public var fontFamily:*;
        public var fontSize:*;
        public var color:*;
        public var fontWeight:*;
        public var fontStyle:*;
        public var backgroundAlpha:*;
        public var backgroundColor:*;
        public var backgroundImage:*;
        public var borderColor:*;
        public var borderStyle:*;
        public var borderRadius:*;
	}
}

////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package org.apache.flex.core
{
	import org.apache.flex.events.Event;
	import org.apache.flex.events.EventDispatcher;

    /**
     *  The SimpleCSSStyles class contains CSS style
     *  properties supported by SimpleCSSValuesImpl.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.2
     *  @playerversion AIR 2.6
     *  @productversion FlexJS 0.0
     */
	public class SimpleCSSStyles
	{
        /**
         *  Constructor.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function SimpleCSSStyles()
		{
			super();
		}

		private var _object:IStyleableObject;

        /**
         *  The object to which these styles apply.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function get object():IStyleableObject
		{
			return _object;
		}

        /**
         *  @private
         */
		public function set object(value:IStyleableObject):void
		{
			if (_object != value)
			{
                _object = value;
			}
		}

        public var top:*;
        public var bottom:*;
        public var left:*;
        public var right:*;
        public var padding:*;
		public var paddingLeft:*;
        public var paddingRight:*;
        public var paddingTop:*;
        public var paddingBottom:*;
        public var margin:*;
        public var marginLeft:*;
        public var marginRight:*;
        public var marginTop:*;
        public var marginBottom:*;
        public var horizontalCenter:*;
        public var verticalCenter:*;
        public var horizontalAlign:*;
        public var verticalAlign:*;
        public var fontFamily:*;
        public var fontSize:*;
        public var color:*;
        public var fontWeight:*;
        public var fontStyle:*;
        public var backgroundAlpha:*;
        public var backgroundColor:*;
        public var backgroundImage:*;
        public var borderColor:*;
        public var borderStyle:*;
        public var borderRadius:*;
	}
}

add margin styles

add margin styles


// vim: tabstop=4 shiftwidth=4

// Copyright (c) 2010 , NetEase.com,Inc. All rights reserved.
//
// Author: Yang Bo (pop.atry@gmail.com)
//
// Use, modification and distribution are subject to the "New BSD License"
// as listed at <url: http://www.opensource.org/licenses/bsd-license.php >.

package com.netease.protobuf {
	import flash.net.*;
	import flash.utils.*;
	import flash.events.*;
	public final class SimpleWebRPC {
		private var urlPrefix:String
		public function SimpleWebRPC(urlPrefix:String) {
			this.urlPrefix = urlPrefix;
		}
		private static const REF:Dictionary = new Dictionary();
		public function send(qualifiedMethodName:String,
							 input:IExternalizable,
							 rpcResult:Function,
							 outputType:Class):void {

			const loader:URLLoader = new URLLoader
			REF[loader] = true;
			loader.dataFormat = URLLoaderDataFormat.BINARY
			loader.addEventListener(Event.COMPLETE, function(event:Event):void {
				delete REF[loader]
				const output:IExternalizable = new outputType
				output.readExternal(loader.data)
				rpcResult(output)
			})
			function errorEventHandler(event:Event):void {
				delete REF[loader]
				rpcResult(event)
			}
			loader.addEventListener(IOErrorEvent.IO_ERROR, errorEventHandler)
			loader.addEventListener(
					SecurityErrorEvent.SECURITY_ERROR, errorEventHandler)
			const request:URLRequest = new URLRequest(
				urlPrefix + qualifiedMethodName.replace(/\./, "/"))
			request.method = URLRequestMethod.POST
			const requestContent:ByteArray = new ByteArray
			input.writeExternal(requestContent)
			request.data = requestContent
			request.contentType = "application/x-protobuf"
			loader.load(request)
		}
	}
}

// vim: tabstop=4 shiftwidth=4

// Copyright (c) 2010 , NetEase.com,Inc. All rights reserved.
//
// Author: Yang Bo (pop.atry@gmail.com)
//
// Use, modification and distribution are subject to the "New BSD License"
// as listed at <url: http://www.opensource.org/licenses/bsd-license.php >.

package com.netease.protobuf {
	import flash.net.*;
	import flash.utils.*;
	import flash.events.*;
	public final class SimpleWebRPC {
		private var urlPrefix:String
		public function SimpleWebRPC(urlPrefix:String) {
			this.urlPrefix = urlPrefix;
		}
		private static const REF:Dictionary = new Dictionary();
		public function send(qualifiedMethodName:String,
							 input:IExternalizable,
							 rpcResult:Function,
							 outputType:Class):void {

			const loader:URLLoader = new URLLoader
			REF[loader] = true;
			loader.dataFormat = URLLoaderDataFormat.BINARY
			loader.addEventListener(Event.COMPLETE, function(event:Event):void {
				delete REF[loader]
				const output:IExternalizable = new outputType
				output.readExternal(loader.data)
				rpcResult(output)
			})
			function errorEventHandler(event:Event):void {
				delete REF[loader]
				rpcResult(event)
			}
			loader.addEventListener(IOErrorEvent.IO_ERROR, errorEventHandler)
			loader.addEventListener(
					SecurityErrorEvent.SECURITY_ERROR, errorEventHandler)
			const request:URLRequest = new URLRequest(
				urlPrefix + qualifiedMethodName.replace(/\./g, "/"))
			request.method = URLRequestMethod.POST
			const requestContent:ByteArray = new ByteArray
			input.writeExternal(requestContent)
			request.data = requestContent
			request.contentType = "application/x-protobuf"
			loader.load(request)
		}
	}
}

替换掉所有的 \.

替换掉所有的 \.


package aerys.minko.type.math
{
	import aerys.minko.ns.minko_math;
	import aerys.minko.type.Factory;
	import aerys.minko.type.Signal;
	import aerys.minko.type.binding.IWatchable;

	import flash.geom.Vector3D;

	public class Vector4 implements IWatchable
	{
		use namespace minko_math;

		public static const X_AXIS				: Vector4	= new Vector4(1., 0., 0.);
		public static const Y_AXIS				: Vector4	= new Vector4(0., 1., 0.);
		public static const Z_AXIS				: Vector4	= new Vector4(0., 0., 1.);
		public static const ZERO				: Vector4	= new Vector4(0., 0., 0., 0.);
		public static const ONE					: Vector4	= new Vector4(1., 1., 1., 1.);
		public static const FORWARD				: Vector4	= Z_AXIS;
		public static const BACKWARD			: Vector4	= new Vector4(0., 0., -1.);
		public static const LEFT				: Vector4	= new Vector4(-1, 0., 0.);
		public static const RIGHT				: Vector4	= new Vector4(1, 0., 0.);
		public static const UP					: Vector4	= Y_AXIS;
		public static const DOWN				: Vector4	= new Vector4(0, -1., 0.);

		private static const FACTORY			: Factory	= Factory.getFactory(Vector4);

		private static const UPDATE_NONE		: uint		= 0;
		private static const UPDATE_LENGTH		: uint		= 1;
		private static const UPDATE_LENGTH_SQ	: uint		= 2;
		private static const UPDATE_ALL			: uint		= 3; // UPDATE_LENGTH | UPDATE_LENGTH_SQ;

		private static const DATA_DESCRIPTOR	: Object	= {
			'x'	: 'x',
			'y'	: 'y',
			'z'	: 'z',
			'w'	: 'w'
		};

		minko_math var _vector	: Vector3D	= new Vector3D();

		private var _update		: uint		= 0;

		private var _length		: Number	= 0.;
		private var _lengthSq	: Number	= 0.;

		private var _locked		: Boolean	= false;
		private var _changed	: Signal	= new Signal('Vector4.changed');

		public function get x()	: Number
		{
			return _vector.x;
		}
		public function set x(value : Number) : void
		{
			if (value != _vector.x)
			{
				_vector.x = value;
				_update = UPDATE_ALL;

				if (!_locked)
					_changed.execute(this);
			}
		}

		public function get y()	: Number
		{
			return _vector.y;
		}
		public function set y(value : Number) : void
		{
			if (value != _vector.y)
			{
				_vector.y = value;
				_update = UPDATE_ALL;

				if (!_locked)
					_changed.execute(this);
			}
		}

		public function get z() : Number
		{
			return _vector.z;
		}
		public function set z(value : Number) : void
		{
			if (value != _vector.z)
			{
				_vector.z = value;
				_update = UPDATE_ALL;

				if (!_locked)
					_changed.execute(this);
			}
		}

		public function get w()	: Number
		{
			return _vector.w;
		}
		public function set w(value : Number) : void
		{
			if (value != _vector.w)
			{
				_vector.w = value;
				_update = UPDATE_ALL;

				if (!_locked)
					_changed.execute(this);
			}
		}

		public function get lengthSquared()	: Number
		{
			if (_update & UPDATE_LENGTH_SQ)
			{
				_update ^= UPDATE_LENGTH_SQ;
				_lengthSq = _vector.x * _vector.x + _vector.y * _vector.y
							+ _vector.z * _vector.z;
			}

			return _lengthSq;
		}

		public function get length() : Number
		{
			if (_update & UPDATE_LENGTH)
			{
				_update ^= UPDATE_LENGTH;
				_length = Math.sqrt(lengthSquared);
			}

			return _length;
		}

		public function get locked() : Boolean
		{
			return _locked;
		}

		public function get changed() : Signal
		{
			return _changed;
		}

		public function Vector4(x 	: Number	= 0.,
								y	: Number	= 0.,
								z	: Number	= 0.,
								w 	: Number	= 1.)
		{
			_vector.x = x;
			_vector.y = y;
			_vector.z = z;
			_vector.w = w;

			_update = UPDATE_ALL;
		}

		public static function add(u 	: Vector4,
								   v 	: Vector4,
								   out	: Vector4 = null) : Vector4
		{
			out ||= new Vector4();
			out.copyFrom(u);

			return out.incrementBy(v);
		}

		public static function subtract(u 	: Vector4,
										v 	: Vector4,
										out : Vector4 = null) : Vector4
		{
			out ||= new Vector4();
			out.copyFrom(u);

			return out.decrementBy(v);
		}

		public static function dotProduct(u : Vector4, v : Vector4) : Number
		{
			return u._vector.dotProduct(v._vector);
		}

		public static function crossProduct(u : Vector4, v : Vector4, out : Vector4 = null) : Vector4
		{
			out ||= FACTORY.create() as Vector4;

			out.set(
				u._vector.y * v._vector.z - v._vector.y * u._vector.z,
				u._vector.z * v._vector.x - v._vector.z * u._vector.x,
				u._vector.x * v._vector.y - v._vector.x * u._vector.y
			);

			return out;
		}

		public function compareTo(v : Vector4, allFour : Boolean = false) : Boolean
		{
			return _vector.x == v._vector.x
				   && _vector.y == v._vector.y
				   && _vector.z == v._vector.z
				   && (!allFour || (_vector.w == v._vector.w));
		}

		public static function distance(u : Vector4, v : Vector4) : Number
		{
			return Vector3D.distance(u._vector, v._vector);
		}

		public function copyFrom(source : Vector4) : Vector4
		{
			return set(source.x, source.y, source.z, source.w);
		}

		public function incrementBy(vector : Vector4) : Vector4
		{
			_vector.incrementBy(vector._vector);

			_update = UPDATE_ALL;
			_changed.execute(this);

			return this;
		}

		public function decrementBy(vector : Vector4) : Vector4
		{
			_vector.decrementBy(vector._vector);

			_update = UPDATE_ALL;
			_changed.execute(this);

			return this;
		}

		public function scaleBy(scale : Number) : Vector4
		{
			_vector.scaleBy(scale);

			_update = UPDATE_ALL;
			_changed.execute(this);

			return this;
		}

		public function lerp(target : Vector4, ratio : Number) : Vector4
		{
			if (ratio == 1.)
				return copyFrom(target);

			if (ratio != 0.)
			{
				var x : Number = _vector.x;
				var y : Number = _vector.y;
				var z : Number = _vector.z;
				var w : Number = _vector.w;

				set(
					x + (target._vector.x - x) * ratio,
					y + (target._vector.y - y) * ratio,
					z + (target._vector.z - z) * ratio,
					w + (target._vector.w - w) * ratio
				);
			}

			return this;
		}

		public function equals(v : Vector4, allFour : Boolean = false, tolerance : Number = 0.) : Boolean
		{
			return tolerance
				? _vector.nearEquals(v._vector, tolerance, allFour)
				: _vector.equals(v._vector, allFour);
		}

		public function project() : Vector4
		{
			_vector.x /= _vector.w;
			_vector.y /= _vector.w;
			_vector.z /= _vector.w;

			_update = UPDATE_ALL;
			_changed.execute(this);

			return this;
		}

		public function normalize() : Vector4
		{
			var l : Number = length;

			if (l != 0.)
			{
				_vector.x /= l;
				_vector.y /= l;
				_vector.z /= l;

				_length = 1.;
				_lengthSq = 1.;

				_update = UPDATE_NONE;
				_changed.execute(this);
			}

			return this;
		}

		public function crossProduct(vector : Vector4) : Vector4
		{
			var x : Number = _vector.x;
			var y : Number = _vector.y;
			var z : Number = _vector.z;

			_vector.x = y * vector._vector.z - vector._vector.y * z;
			_vector.y = z * vector._vector.x - vector._vector.z * x;
			_vector.z = x * vector._vector.y - vector._vector.x * y;

			_update = UPDATE_ALL;
			_changed.execute(this);

			return this;
		}

		public function getVector3D() : Vector3D
		{
			return _vector.clone();
		}

		public function set(x : Number,
							y : Number,
							z : Number,
							w : Number = 1.) : Vector4
		{
			if (x != _vector.x || y != _vector.y || z != _vector.z || w != _vector.w)
			{
				_vector.setTo(x, y, z);
				_vector.w = w;

				_update = UPDATE_ALL;
				if (!_locked)
					_changed.execute(this);
			}

			return this;
		}

		public function toString() : String
		{
			return '(' + _vector.x + ', ' + _vector.y + ', ' + _vector.z + ', ' + _vector.w + ')';
		}

		public static function scale(v : Vector4, s : Number, out : Vector4 = null) : Vector4
		{
			out ||= FACTORY.create() as Vector4;
			out.set(v._vector.x * s, v._vector.y * s, v._vector.z * s, v._vector.w * s);

			return out;
		}

		public function toVector3D(out : Vector3D = null) : Vector3D
		{
			if (!out)
				return _vector.clone();

			out.x = _vector.x;
			out.y = _vector.y;
			out.z = _vector.z;
			out.w = _vector.w;

			return out;
		}

		public function lock() : void
		{
			_locked = true;
		}

		public function unlock() : void
		{
			_locked = false;
			_changed.execute(this);
		}

		public function clone() : Vector4
		{
			return new Vector4(_vector.x, _vector.y, _vector.z, _vector.w);
		}
	}
}

package aerys.minko.type.math
{
	import aerys.minko.ns.minko_math;
	import aerys.minko.type.Factory;
	import aerys.minko.type.Signal;
	import aerys.minko.type.binding.IWatchable;

	import flash.geom.Vector3D;

	public class Vector4 implements IWatchable
	{
		use namespace minko_math;

		public static const X_AXIS				: Vector4	= new Vector4(1., 0., 0.);
		public static const Y_AXIS				: Vector4	= new Vector4(0., 1., 0.);
		public static const Z_AXIS				: Vector4	= new Vector4(0., 0., 1.);
		public static const ZERO				: Vector4	= new Vector4(0., 0., 0., 0.);
		public static const ONE					: Vector4	= new Vector4(1., 1., 1., 1.);
		public static const FORWARD				: Vector4	= Z_AXIS;
		public static const BACKWARD			: Vector4	= new Vector4(0., 0., -1.);
		public static const LEFT				: Vector4	= new Vector4(-1, 0., 0.);
		public static const RIGHT				: Vector4	= new Vector4(1, 0., 0.);
		public static const UP					: Vector4	= Y_AXIS;
		public static const DOWN				: Vector4	= new Vector4(0, -1., 0.);

		private static const FACTORY			: Factory	= Factory.getFactory(Vector4);

		private static const UPDATE_NONE		: uint		= 0;
		private static const UPDATE_LENGTH		: uint		= 1;
		private static const UPDATE_LENGTH_SQ	: uint		= 2;
		private static const UPDATE_ALL			: uint		= 3; // UPDATE_LENGTH | UPDATE_LENGTH_SQ;

		private static const DATA_DESCRIPTOR	: Object	= {
			'x'	: 'x',
			'y'	: 'y',
			'z'	: 'z',
			'w'	: 'w'
		};

		minko_math var _vector	: Vector3D	= new Vector3D();

		private var _update		: uint		= 0;

		private var _length		: Number	= 0.;
		private var _lengthSq	: Number	= 0.;

		private var _locked		: Boolean	= false;
		private var _changed	: Signal	= new Signal('Vector4.changed');

		public function get x()	: Number
		{
			return _vector.x;
		}
		public function set x(value : Number) : void
		{
			if (value != _vector.x)
			{
				_vector.x = value;
				_update = UPDATE_ALL;

				if (!_locked)
					_changed.execute(this);
			}
		}

		public function get y()	: Number
		{
			return _vector.y;
		}
		public function set y(value : Number) : void
		{
			if (value != _vector.y)
			{
				_vector.y = value;
				_update = UPDATE_ALL;

				if (!_locked)
					_changed.execute(this);
			}
		}

		public function get z() : Number
		{
			return _vector.z;
		}
		public function set z(value : Number) : void
		{
			if (value != _vector.z)
			{
				_vector.z = value;
				_update = UPDATE_ALL;

				if (!_locked)
					_changed.execute(this);
			}
		}

		public function get w()	: Number
		{
			return _vector.w;
		}
		public function set w(value : Number) : void
		{
			if (value != _vector.w)
			{
				_vector.w = value;
				_update = UPDATE_ALL;

				if (!_locked)
					_changed.execute(this);
			}
		}

		public function get lengthSquared()	: Number
		{
			if (_update & UPDATE_LENGTH_SQ)
			{
				_update ^= UPDATE_LENGTH_SQ;
				_lengthSq = _vector.x * _vector.x + _vector.y * _vector.y
							+ _vector.z * _vector.z;
			}

			return _lengthSq;
		}

		public function get length() : Number
		{
			if (_update & UPDATE_LENGTH)
			{
				_update ^= UPDATE_LENGTH;
				_length = Math.sqrt(lengthSquared);
			}

			return _length;
		}

		public function get locked() : Boolean
		{
			return _locked;
		}

		public function get changed() : Signal
		{
			return _changed;
		}

		public function Vector4(x 	: Number	= 0.,
								y	: Number	= 0.,
								z	: Number	= 0.,
								w 	: Number	= 1.)
		{
			_vector.x = x;
			_vector.y = y;
			_vector.z = z;
			_vector.w = w;

			_update = UPDATE_ALL;
		}

		public static function add(u 	: Vector4,
								   v 	: Vector4,
								   out	: Vector4 = null) : Vector4
		{
			out ||= new Vector4();
			out.copyFrom(u);

			return out.incrementBy(v);
		}

		public static function subtract(u 	: Vector4,
										v 	: Vector4,
										out : Vector4 = null) : Vector4
		{
			out ||= new Vector4();
			out.copyFrom(u);

			return out.decrementBy(v);
		}

		public static function dotProduct(u : Vector4, v : Vector4) : Number
		{
			return u._vector.dotProduct(v._vector);
		}

		public static function crossProduct(u : Vector4, v : Vector4, out : Vector4 = null) : Vector4
		{
			out ||= FACTORY.create() as Vector4;

			out.set(
				u._vector.y * v._vector.z - v._vector.y * u._vector.z,
				u._vector.z * v._vector.x - v._vector.z * u._vector.x,
				u._vector.x * v._vector.y - v._vector.x * u._vector.y
			);

			return out;
		}

		public static function distance(u : Vector4, v : Vector4) : Number
		{
			return Vector3D.distance(u._vector, v._vector);
		}

		public function copyFrom(source : Vector4) : Vector4
		{
			return set(source.x, source.y, source.z, source.w);
		}

		public function incrementBy(vector : Vector4) : Vector4
		{
			_vector.incrementBy(vector._vector);

			_update = UPDATE_ALL;
			_changed.execute(this);

			return this;
		}

		public function decrementBy(vector : Vector4) : Vector4
		{
			_vector.decrementBy(vector._vector);

			_update = UPDATE_ALL;
			_changed.execute(this);

			return this;
		}

		public function scaleBy(scale : Number) : Vector4
		{
			_vector.scaleBy(scale);

			_update = UPDATE_ALL;
			_changed.execute(this);

			return this;
		}

		public function lerp(target : Vector4, ratio : Number) : Vector4
		{
			if (ratio == 1.)
				return copyFrom(target);

			if (ratio != 0.)
			{
				var x : Number = _vector.x;
				var y : Number = _vector.y;
				var z : Number = _vector.z;
				var w : Number = _vector.w;

				set(
					x + (target._vector.x - x) * ratio,
					y + (target._vector.y - y) * ratio,
					z + (target._vector.z - z) * ratio,
					w + (target._vector.w - w) * ratio
				);
			}

			return this;
		}

		public function equals(v : Vector4, allFour : Boolean = false, tolerance : Number = 0.) : Boolean
		{
			return tolerance
				? _vector.nearEquals(v._vector, tolerance, allFour)
				: _vector.equals(v._vector, allFour);
		}

		public function project() : Vector4
		{
			_vector.x /= _vector.w;
			_vector.y /= _vector.w;
			_vector.z /= _vector.w;

			_update = UPDATE_ALL;
			_changed.execute(this);

			return this;
		}

		public function normalize() : Vector4
		{
			var l : Number = length;

			if (l != 0.)
			{
				_vector.x /= l;
				_vector.y /= l;
				_vector.z /= l;

				_length = 1.;
				_lengthSq = 1.;

				_update = UPDATE_NONE;
				_changed.execute(this);
			}

			return this;
		}

		public function crossProduct(vector : Vector4) : Vector4
		{
			var x : Number = _vector.x;
			var y : Number = _vector.y;
			var z : Number = _vector.z;

			_vector.x = y * vector._vector.z - vector._vector.y * z;
			_vector.y = z * vector._vector.x - vector._vector.z * x;
			_vector.z = x * vector._vector.y - vector._vector.x * y;

			_update = UPDATE_ALL;
			_changed.execute(this);

			return this;
		}

		public function getVector3D() : Vector3D
		{
			return _vector.clone();
		}

		public function set(x : Number,
							y : Number,
							z : Number,
							w : Number = 1.) : Vector4
		{
			if (x != _vector.x || y != _vector.y || z != _vector.z || w != _vector.w)
			{
				_vector.setTo(x, y, z);
				_vector.w = w;

				_update = UPDATE_ALL;
				if (!_locked)
					_changed.execute(this);
			}

			return this;
		}

		public function toString() : String
		{
			return '(' + _vector.x + ', ' + _vector.y + ', ' + _vector.z + ', ' + _vector.w + ')';
		}

		public static function scale(v : Vector4, s : Number, out : Vector4 = null) : Vector4
		{
			out ||= FACTORY.create() as Vector4;
			out.set(v._vector.x * s, v._vector.y * s, v._vector.z * s, v._vector.w * s);

			return out;
		}

		public function toVector3D(out : Vector3D = null) : Vector3D
		{
			if (!out)
				return _vector.clone();

			out.x = _vector.x;
			out.y = _vector.y;
			out.z = _vector.z;
			out.w = _vector.w;

			return out;
		}

		public function lock() : void
		{
			_locked = true;
		}

		public function unlock() : void
		{
			_locked = false;
			_changed.execute(this);
		}

		public function clone() : Vector4
		{
			return new Vector4(_vector.x, _vector.y, _vector.z, _vector.w);
		}
	}
}

remove duplicate Vector4.compareTo() method, use Vector4.equals() instead


//
// $Id$
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package com.threerings.util {

import flash.events.NetStatusEvent;
import flash.events.EventDispatcher;

import flash.net.SharedObject;
import flash.net.SharedObjectFlushStatus;

/**
 * Dispatched when this Config object has a value set on it.
 *
 * @eventType com.threerings.util.ConfigValueSetEvent.CONFIG_VALUE_SET
 */
[Event(name="ConfigValSet", type="com.threerings.util.ConfigValueSetEvent")]

public class Config extends EventDispatcher
{
    /**
     * Constructs a new config object which will obtain configuration
     * information from the specified path.
     */
    public function Config (path :String)
    {
        setPath(path);
    }

    public function setPath (path :String) :void
    {
        _so = (path == null) ? null : SharedObject.getLocal("config_" + path, "/");
        _data = (_so == null) ? {} : _so.data;

        // dispatch events for all settings
        for (var n :String in _data) {
            dispatchEvent(new ConfigValueSetEvent(n, _data[n]));
        }
    }

    /**
     * Fetches and returns the value for the specified configuration property.
     */
    public function getValue (name :String, defValue :Object) :Object
    {
        var val :* = _data[name];
        return (val === undefined) ? defValue : val;
    }

    /**
     * Returns the value specified.
     */
    public function setValue (name :String, value :Object) :void
    {
        _data[name] = value;
        if (_so != null) {
            _so.flush(); // flushing is not strictly necessary
        }

        // dispatch an event corresponding
        dispatchEvent(new ConfigValueSetEvent(name, value));
    }

    /**
     * Remove any set value for the specified preference.
     * This does not dispatch an event because this would only be done to remove an
     * obsolete preference.
     */
    public function remove (name :String) :void
    {
        delete _data[name];
        if (_so != null) {
            _so.flush(); // flushing is not strictly necessary
        }
    }

    /**
     * Ensure that we can store preferences up to the specified size.
     * Note that calling this method may pop up a dialog to the user, asking
     * them if it's ok to increase the capacity. The result listener may
     * never be called if the user doesn't answer the pop-up.
     *
     * @param rl an optional listener that will be informed as to whether
     * the request succeeded.
     */
    public function ensureCapacity (kilobytes :int, rl :ResultListener) :void
    {
        if (_so == null) {
            if (rl != null) {
                rl.requestCompleted(this);
            }
            return;
        }

        // flush with the size, see if we're cool
        var result :String = _so.flush(1024 * kilobytes);
        if (rl == null) {
            return;
        }

        // success
        if (result == SharedObjectFlushStatus.FLUSHED) {
            rl.requestCompleted(this);
            return;
        }

        // otherwise we'll hear back in a sec
        var thisConfig :Config = this;
        var listener :Function = function (evt :NetStatusEvent) :void {
                // TODO: There is a bug where the status is always
                // "SharedObject.Flush.Failed", even on success, if the request
                // was for a large enough storage that the player calls it
                // "unlimited".
                trace("================[" + evt.info.code + "]");
                if ("SharedObject.Flush.Success" == evt.info.code) {
                    rl.requestCompleted(thisConfig);
                } else {
                    rl.requestFailed(new Error(String(evt.info.code)));
                }
                _so.removeEventListener(NetStatusEvent.NET_STATUS, listener);
            };

        _so.addEventListener(NetStatusEvent.NET_STATUS, listener);
    }

    /** The shared object that contains our preferences. */
    protected var _so :SharedObject;

    /** The object in which we store things, usually _so.data. */
    protected var _data :Object;
}
}

//
// $Id$
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package com.threerings.util {

import flash.events.NetStatusEvent;
import flash.events.EventDispatcher;

import flash.net.SharedObject;
import flash.net.SharedObjectFlushStatus;

/**
 * Dispatched when this Config object has a value set on it.
 *
 * @eventType com.threerings.util.ConfigValueSetEvent.CONFIG_VALUE_SET
 */
[Event(name="ConfigValSet", type="com.threerings.util.ConfigValueSetEvent")]

public class Config extends EventDispatcher
{
    /**
     * Constructs a new config object which will obtain configuration
     * information from the specified path.
     */
    public function Config (path :String)
    {
        setPath(path);
    }

    /**
     * Set the path, if null then we aren't persisting settings.
     */
    public function setPath (path :String) :void
    {
        _so = (path == null) ? null : SharedObject.getLocal("config_" + path, "/");
        _data = (_so == null) ? {} : _so.data;

        // dispatch events for all settings
        for (var n :String in _data) {
            dispatchEvent(new ConfigValueSetEvent(n, _data[n]));
        }
    }

    /**
     * Are we persisting settings?
     */
    public function isPersisting () :Boolean
    {
        return (_so != null);
    }

    /**
     * Fetches and returns the value for the specified configuration property.
     */
    public function getValue (name :String, defValue :Object) :Object
    {
        var val :* = _data[name];
        return (val === undefined) ? defValue : val;
    }

    /**
     * Returns the value specified.
     */
    public function setValue (name :String, value :Object) :void
    {
        _data[name] = value;
        if (_so != null) {
            _so.flush(); // flushing is not strictly necessary
        }

        // dispatch an event corresponding
        dispatchEvent(new ConfigValueSetEvent(name, value));
    }

    /**
     * Remove any set value for the specified preference.
     * This does not dispatch an event because this would only be done to remove an
     * obsolete preference.
     */
    public function remove (name :String) :void
    {
        delete _data[name];
        if (_so != null) {
            _so.flush(); // flushing is not strictly necessary
        }
    }

    /**
     * Ensure that we can store preferences up to the specified size.
     * Note that calling this method may pop up a dialog to the user, asking
     * them if it's ok to increase the capacity. The result listener may
     * never be called if the user doesn't answer the pop-up.
     *
     * @param rl an optional listener that will be informed as to whether
     * the request succeeded.
     */
    public function ensureCapacity (kilobytes :int, rl :ResultListener) :void
    {
        if (_so == null) {
            if (rl != null) {
                rl.requestCompleted(this);
            }
            return;
        }

        // flush with the size, see if we're cool
        var result :String = _so.flush(1024 * kilobytes);
        if (rl == null) {
            return;
        }

        // success
        if (result == SharedObjectFlushStatus.FLUSHED) {
            rl.requestCompleted(this);
            return;
        }

        // otherwise we'll hear back in a sec
        var thisConfig :Config = this;
        var listener :Function = function (evt :NetStatusEvent) :void {
                // TODO: There is a bug where the status is always
                // "SharedObject.Flush.Failed", even on success, if the request
                // was for a large enough storage that the player calls it
                // "unlimited".
                trace("================[" + evt.info.code + "]");
                if ("SharedObject.Flush.Success" == evt.info.code) {
                    rl.requestCompleted(thisConfig);
                } else {
                    rl.requestFailed(new Error(String(evt.info.code)));
                }
                _so.removeEventListener(NetStatusEvent.NET_STATUS, listener);
            };

        _so.addEventListener(NetStatusEvent.NET_STATUS, listener);
    }

    /** The shared object that contains our preferences. */
    protected var _so :SharedObject;

    /** The object in which we store things, usually _so.data. */
    protected var _data :Object;
}
}

Allow whether we're persisting to be queried.

git-svn-id: a1a4b28b82a3276cc491891159dd9963a0a72fae@5672 542714f4-19e9-0310-aa3c-eee0fc999fb1


package aerys.minko.type.math
{
	import aerys.minko.ns.minko_math;
	import aerys.minko.type.Factory;
	import aerys.minko.type.Signal;
	import aerys.minko.type.binding.IWatchable;

	import flash.geom.Vector3D;

	public class Vector4 implements IWatchable
	{
		use namespace minko_math;

		public static const X_AXIS				: Vector4	= new Vector4(1., 0., 0.);
		public static const Y_AXIS				: Vector4	= new Vector4(0., 1., 0.);
		public static const Z_AXIS				: Vector4	= new Vector4(0., 0., 1.);
		public static const ZERO				: Vector4	= new Vector4(0., 0., 0., 0.);
		public static const ONE					: Vector4	= new Vector4(1., 1., 1., 1.);
		public static const FORWARD				: Vector4	= Z_AXIS;
		public static const BACKWARD			: Vector4	= new Vector4(0., 0., -1.);
		public static const LEFT				: Vector4	= new Vector4(-1, 0., 0.);
		public static const RIGHT				: Vector4	= new Vector4(1, 0., 0.);
		public static const UP					: Vector4	= Y_AXIS;
		public static const DOWN				: Vector4	= new Vector4(0, -1., 0.);

		private static const FACTORY			: Factory	= Factory.getFactory(Vector4);

		private static const UPDATE_NONE		: uint		= 0;
		private static const UPDATE_LENGTH		: uint		= 1;
		private static const UPDATE_LENGTH_SQ	: uint		= 2;
		private static const UPDATE_ALL			: uint		= 3; // UPDATE_LENGTH | UPDATE_LENGTH_SQ;

		private static const DATA_DESCRIPTOR	: Object	= {
			'x'	: 'x',
			'y'	: 'y',
			'z'	: 'z',
			'w'	: 'w'
		}

		minko_math var _vector	: Vector3D	= new Vector3D();

		private var _update		: uint		= 0;

		private var _length		: Number	= 0.;
		private var _lengthSq	: Number	= 0.;

		private var _locked		: Boolean	= false;
		private var _changed	: Signal	= new Signal('Vector4.changed');

		public function get x()	: Number
		{
			return _vector.x;
		}
		public function set x(value : Number) : void
		{
			if (value != _vector.x)
			{
				_vector.x = value;
				_update = UPDATE_ALL;

				if (!_locked)
					_changed.execute(this);
			}
		}

		public function get y()	: Number
		{
			return _vector.y;
		}
		public function set y(value : Number) : void
		{
			if (value != _vector.y)
			{
				_vector.y = value;
				_update = UPDATE_ALL;

				if (!_locked)
					_changed.execute(this);
			}
		}

		public function get z() : Number
		{
			return _vector.z;
		}
		public function set z(value : Number) : void
		{
			if (value != _vector.z)
			{
				_vector.z = value;
				_update = UPDATE_ALL;

				if (!_locked)
					_changed.execute(this);
			}
		}

		public function get w()	: Number
		{
			return _vector.w;
		}
		public function set w(value : Number) : void
		{
			if (value != _vector.w)
			{
				_vector.w = value;
				_update = UPDATE_ALL;

				if (!_locked)
					_changed.execute(this);
			}
		}

		public function get lengthSquared()	: Number
		{
			if (_update & UPDATE_LENGTH_SQ)
			{
				_update ^= UPDATE_LENGTH_SQ;
				_lengthSq = _vector.x * _vector.x + _vector.y * _vector.y
							+ _vector.z * _vector.z;
			}

			return _lengthSq;
		}

		public function get length() : Number
		{
			if (_update & UPDATE_LENGTH)
			{
				_update ^= UPDATE_LENGTH;
				_length = Math.sqrt(lengthSquared);
			}

			return _length;
		}

		public function get locked() : Boolean
		{
			return _locked;
		}

		public function get changed() : Signal
		{
			return _changed;
		}

		public function Vector4(x 	: Number	= 0.,
								y	: Number	= 0.,
								z	: Number	= 0.,
								w 	: Number	= 1.)
		{
			_vector.x = x;
			_vector.y = y;
			_vector.z = z;
			_vector.w = w;

			_update = UPDATE_ALL;
		}

		public static function add(u 	: Vector4,
								   v 	: Vector4,
								   out	: Vector4 = null) : Vector4
		{
			out = copy(u, out);

			return out.incrementBy(v);
		}

		public static function subtract(u 	: Vector4,
										v 	: Vector4,
										out : Vector4 = null) : Vector4
		{
			out = copy(u, out);

			return out.decrementBy(v);
		}

		public static function dotProduct(u : Vector4, v : Vector4) : Number
		{
			return u._vector.dotProduct(v._vector);
		}

		public static function crossProduct(u : Vector4, v : Vector4) : Vector4
		{
			return new Vector4(
				u._vector.y * v._vector.z - v._vector.y * u._vector.z,
				u._vector.z * v._vector.x - v._vector.z * u._vector.x,
				u._vector.x * v._vector.y - v._vector.x * u._vector.y
			);
		}

		public function compareTo(v : Vector4, allFour : Boolean = false) : Boolean
		{
			return _vector.x == v._vector.x
				   && _vector.y == v._vector.y
				   && _vector.z == v._vector.z
				   && (!allFour || (_vector.w == v._vector.w));
		}

		public static function distance(u : Vector4, v : Vector4) : Number
		{
			return Vector3D.distance(u._vector, v._vector);
		}

		public static function copy(source : Vector4, target : Vector4 = null) : Vector4
		{
			target ||= FACTORY.create() as Vector4;
			target.set(source.x, source.y, source.z, source.w);

			return target;
		}

		public function incrementBy(vector : Vector4) : Vector4
		{
			_vector.incrementBy(vector._vector);

			_update = UPDATE_ALL;
			_changed.execute(this);

			return this;
		}

		public function decrementBy(vector : Vector4) : Vector4
		{
			_vector.decrementBy(vector._vector);

			_update = UPDATE_ALL;
			_changed.execute(this);

			return this;
		}

		public function scaleBy(scale : Number) : Vector4
		{
			_vector.scaleBy(scale);

			_update = UPDATE_ALL;
			_changed.execute(this);

			return this;
		}

		public function project() : Vector4
		{
			_vector.x /= _vector.w;
			_vector.y /= _vector.w;
			_vector.z /= _vector.w;

			_update = UPDATE_ALL;
			_changed.execute(this);

			return this;
		}

		public function normalize() : Vector4
		{
			var l : Number = length;

			if (l != 0.)
			{
				_vector.x /= l;
				_vector.y /= l;
				_vector.z /= l;

				_length = 1.;
				_lengthSq = 1.;

				_update = UPDATE_NONE;
				_changed.execute(this);
			}

			return this;
		}

		public function crossProduct(vector : Vector4) : Vector4
		{
			var x : Number = _vector.x;
			var y : Number = _vector.y;
			var z : Number = _vector.z;

			_vector.x = y * vector._vector.z - vector._vector.y * z;
			_vector.y = z * vector._vector.x - vector._vector.z * x;
			_vector.z = x * vector._vector.y - vector._vector.x * y;

			_update = UPDATE_ALL;
			_changed.execute(this);

			return this;
		}

		public function getVector3D() : Vector3D
		{
			return _vector.clone();
		}

		public function set(x : Number,
							y : Number,
							z : Number,
							w : Number = 1.) : Vector4
		{
			if (x != _vector.x || y != _vector.y || z != _vector.z || w != _vector.w)
			{
				_vector.x = x;
				_vector.y = y;
				_vector.z = z;
				_vector.w = w;

				_update = UPDATE_ALL;
				if (!_locked)
					_changed.execute(this);
			}

			return this;
		}

		public function toString() : String
		{
			return "(" + _vector.x + ", " + _vector.y + ", " + _vector.z + ", "
				   + _vector.w + ")";
		}

		public static function scale(v : Vector4, s : Number, out : Vector4 = null) : Vector4
		{
			out ||= FACTORY.create() as Vector4;
			out._vector.x = v._vector.x;
			out._vector.y = v._vector.y;
			out._vector.z = v._vector.z;
			out._vector.w = v._vector.w;

			return out;
		}

		public function toVector3D(out : Vector3D = null) : Vector3D
		{
			if (!out)
				return _vector.clone();

			out.x = _vector.x;
			out.y = _vector.y;
			out.z = _vector.z;
			out.w = _vector.w;

			return out;
		}

		public static function normalize(v : Vector4, out : Vector4 = null) : Vector4
		{
			out = copy(v, out);

			return out.normalize();
		}

		public function lock() : void
		{
			_locked = true;
		}

		public function unlock() : void
		{
			_locked = false;
			_changed.execute(this);
		}

		public function clone() : Vector4
		{
			return new Vector4(_vector.x, _vector.y, _vector.z, _vector.w);
		}
	}
}

package aerys.minko.type.math
{
	import aerys.minko.ns.minko_math;
	import aerys.minko.type.Factory;
	import aerys.minko.type.Signal;
	import aerys.minko.type.binding.IWatchable;

	import flash.geom.Vector3D;

	public class Vector4 implements IWatchable
	{
		use namespace minko_math;

		public static const X_AXIS				: Vector4	= new Vector4(1., 0., 0.);
		public static const Y_AXIS				: Vector4	= new Vector4(0., 1., 0.);
		public static const Z_AXIS				: Vector4	= new Vector4(0., 0., 1.);
		public static const ZERO				: Vector4	= new Vector4(0., 0., 0., 0.);
		public static const ONE					: Vector4	= new Vector4(1., 1., 1., 1.);
		public static const FORWARD				: Vector4	= Z_AXIS;
		public static const BACKWARD			: Vector4	= new Vector4(0., 0., -1.);
		public static const LEFT				: Vector4	= new Vector4(-1, 0., 0.);
		public static const RIGHT				: Vector4	= new Vector4(1, 0., 0.);
		public static const UP					: Vector4	= Y_AXIS;
		public static const DOWN				: Vector4	= new Vector4(0, -1., 0.);

		private static const FACTORY			: Factory	= Factory.getFactory(Vector4);

		private static const UPDATE_NONE		: uint		= 0;
		private static const UPDATE_LENGTH		: uint		= 1;
		private static const UPDATE_LENGTH_SQ	: uint		= 2;
		private static const UPDATE_ALL			: uint		= 3; // UPDATE_LENGTH | UPDATE_LENGTH_SQ;

		private static const DATA_DESCRIPTOR	: Object	= {
			'x'	: 'x',
			'y'	: 'y',
			'z'	: 'z',
			'w'	: 'w'
		}

		minko_math var _vector	: Vector3D	= new Vector3D();

		private var _update		: uint		= 0;

		private var _length		: Number	= 0.;
		private var _lengthSq	: Number	= 0.;

		private var _locked		: Boolean	= false;
		private var _changed	: Signal	= new Signal('Vector4.changed');

		public function get x()	: Number
		{
			return _vector.x;
		}
		public function set x(value : Number) : void
		{
			if (value != _vector.x)
			{
				_vector.x = value;
				_update = UPDATE_ALL;

				if (!_locked)
					_changed.execute(this);
			}
		}

		public function get y()	: Number
		{
			return _vector.y;
		}
		public function set y(value : Number) : void
		{
			if (value != _vector.y)
			{
				_vector.y = value;
				_update = UPDATE_ALL;

				if (!_locked)
					_changed.execute(this);
			}
		}

		public function get z() : Number
		{
			return _vector.z;
		}
		public function set z(value : Number) : void
		{
			if (value != _vector.z)
			{
				_vector.z = value;
				_update = UPDATE_ALL;

				if (!_locked)
					_changed.execute(this);
			}
		}

		public function get w()	: Number
		{
			return _vector.w;
		}
		public function set w(value : Number) : void
		{
			if (value != _vector.w)
			{
				_vector.w = value;
				_update = UPDATE_ALL;

				if (!_locked)
					_changed.execute(this);
			}
		}

		public function get lengthSquared()	: Number
		{
			if (_update & UPDATE_LENGTH_SQ)
			{
				_update ^= UPDATE_LENGTH_SQ;
				_lengthSq = _vector.x * _vector.x + _vector.y * _vector.y
							+ _vector.z * _vector.z;
			}

			return _lengthSq;
		}

		public function get length() : Number
		{
			if (_update & UPDATE_LENGTH)
			{
				_update ^= UPDATE_LENGTH;
				_length = Math.sqrt(lengthSquared);
			}

			return _length;
		}

		public function get locked() : Boolean
		{
			return _locked;
		}

		public function get changed() : Signal
		{
			return _changed;
		}

		public function Vector4(x 	: Number	= 0.,
								y	: Number	= 0.,
								z	: Number	= 0.,
								w 	: Number	= 1.)
		{
			_vector.x = x;
			_vector.y = y;
			_vector.z = z;
			_vector.w = w;

			_update = UPDATE_ALL;
		}

		public static function add(u 	: Vector4,
								   v 	: Vector4,
								   out	: Vector4 = null) : Vector4
		{
			out = copy(u, out);

			return out.incrementBy(v);
		}

		public static function subtract(u 	: Vector4,
										v 	: Vector4,
										out : Vector4 = null) : Vector4
		{
			out = copy(u, out);

			return out.decrementBy(v);
		}

		public static function dotProduct(u : Vector4, v : Vector4) : Number
		{
			return u._vector.dotProduct(v._vector);
		}

		public static function crossProduct(u : Vector4, v : Vector4) : Vector4
		{
			return new Vector4(
				u._vector.y * v._vector.z - v._vector.y * u._vector.z,
				u._vector.z * v._vector.x - v._vector.z * u._vector.x,
				u._vector.x * v._vector.y - v._vector.x * u._vector.y
			);
		}

		public function compareTo(v : Vector4, allFour : Boolean = false) : Boolean
		{
			return _vector.x == v._vector.x
				   && _vector.y == v._vector.y
				   && _vector.z == v._vector.z
				   && (!allFour || (_vector.w == v._vector.w));
		}

		public static function distance(u : Vector4, v : Vector4) : Number
		{
			return Vector3D.distance(u._vector, v._vector);
		}

		public static function copy(source : Vector4, target : Vector4 = null) : Vector4
		{
			target ||= FACTORY.create() as Vector4;
			target.set(source.x, source.y, source.z, source.w);

			return target;
		}

		public function incrementBy(vector : Vector4) : Vector4
		{
			_vector.incrementBy(vector._vector);

			_update = UPDATE_ALL;
			_changed.execute(this);

			return this;
		}

		public function decrementBy(vector : Vector4) : Vector4
		{
			_vector.decrementBy(vector._vector);

			_update = UPDATE_ALL;
			_changed.execute(this);

			return this;
		}

		public function scaleBy(scale : Number) : Vector4
		{
			_vector.scaleBy(scale);

			_update = UPDATE_ALL;
			_changed.execute(this);

			return this;
		}

		public function project() : Vector4
		{
			_vector.x /= _vector.w;
			_vector.y /= _vector.w;
			_vector.z /= _vector.w;

			_update = UPDATE_ALL;
			_changed.execute(this);

			return this;
		}

		public function normalize() : Vector4
		{
			var l : Number = length;

			if (l != 0.)
			{
				_vector.x /= l;
				_vector.y /= l;
				_vector.z /= l;

				_length = 1.;
				_lengthSq = 1.;

				_update = UPDATE_NONE;
				_changed.execute(this);
			}

			return this;
		}

		public function crossProduct(vector : Vector4) : Vector4
		{
			var x : Number = _vector.x;
			var y : Number = _vector.y;
			var z : Number = _vector.z;

			_vector.x = y * vector._vector.z - vector._vector.y * z;
			_vector.y = z * vector._vector.x - vector._vector.z * x;
			_vector.z = x * vector._vector.y - vector._vector.x * y;

			_update = UPDATE_ALL;
			_changed.execute(this);

			return this;
		}

		public function getVector3D() : Vector3D
		{
			return _vector.clone();
		}

		public function set(x : Number,
							y : Number,
							z : Number,
							w : Number = 1.) : Vector4
		{
			if (x != _vector.x || y != _vector.y || z != _vector.z || w != _vector.w)
			{
				_vector.x = x;
				_vector.y = y;
				_vector.z = z;
				_vector.w = w;

				_update = UPDATE_ALL;
				if (!_locked)
					_changed.execute(this);
			}

			return this;
		}

		public function toString() : String
		{
			return "(" + _vector.x + ", " + _vector.y + ", " + _vector.z + ", "
				   + _vector.w + ")";
		}

		public static function scale(v : Vector4, s : Number, out : Vector4 = null) : Vector4
		{
			out ||= FACTORY.create() as Vector4;
			out.set(v._vector.x * s, v._vector.y * s, v._vector.z * s, v._vector.w * s);

			return out;
		}

		public function toVector3D(out : Vector3D = null) : Vector3D
		{
			if (!out)
				return _vector.clone();

			out.x = _vector.x;
			out.y = _vector.y;
			out.z = _vector.z;
			out.w = _vector.w;

			return out;
		}

		public static function normalize(v : Vector4, out : Vector4 = null) : Vector4
		{
			out = copy(v, out);

			return out.normalize();
		}

		public function lock() : void
		{
			_locked = true;
		}

		public function unlock() : void
		{
			_locked = false;
			_changed.execute(this);
		}

		public function clone() : Vector4
		{
			return new Vector4(_vector.x, _vector.y, _vector.z, _vector.w);
		}
	}
}

fix Vector4::scale()

fix Vector4::scale()


////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package shim
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;

	import org.apache.flex.html.Container;

	[DefaultProperty("mxmlContent")]

    /**
     *  A VBox approximation.
     */
	public class VBox extends Container
	{
        /**
         *  Constructor.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function VBox()
		{
			super();
		}

	}
}

////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package shim
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;

	import org.apache.flex.html.Container;
	import org.apache.flex.html.beads.layouts.NonVirtualVerticalLayout;

	[DefaultProperty("mxmlContent")]

    /**
     *  A VBox approximation.
     */
	public class VBox extends Container
	{
        /**
         *  Constructor.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function VBox()
		{
			super();
			addBead(new NonVirtualVerticalLayout());
		}

	}
}

put the v in the vbox

put the v in the vbox


package aerys.minko.render.shader.part.environment
{
	import aerys.minko.render.material.environment.EnvironmentMappingProperties;
	import aerys.minko.render.shader.SFloat;
	import aerys.minko.render.shader.Shader;
	import aerys.minko.render.shader.part.BlendingShaderPart;
	import aerys.minko.render.shader.part.phong.LightAwareShaderPart;
	import aerys.minko.render.shader.part.projection.BlinnNewellProjectionShaderPart;
	import aerys.minko.render.shader.part.projection.ProbeProjectionShaderPart;
	import aerys.minko.type.enum.Blending;
	import aerys.minko.type.enum.EnvironmentMappingType;
	import aerys.minko.type.enum.SamplerDimension;
	import aerys.minko.type.enum.SamplerFiltering;
	import aerys.minko.type.enum.SamplerFormat;
	import aerys.minko.type.enum.SamplerMipMapping;
	import aerys.minko.type.enum.SamplerWrapping;

	import flash.geom.Rectangle;

	public class EnvironmentMappingShaderPart extends LightAwareShaderPart
	{
		private var _blinnNewellProjectionPart	: BlinnNewellProjectionShaderPart;
		private var _probeProjectionPart		: ProbeProjectionShaderPart;
		private var _blending					: BlendingShaderPart;

		public function EnvironmentMappingShaderPart(main : Shader)
		{
			super(main);

			_blinnNewellProjectionPart	= new BlinnNewellProjectionShaderPart(main);
			_probeProjectionPart		= new ProbeProjectionShaderPart(main);
			_blending					= new BlendingShaderPart(main);
		}

		public function getEnvironmentColor() : SFloat
		{
            if (!meshBindings.propertyExists(EnvironmentMappingProperties.ENVIRONMENT_MAPPING_TYPE)
                || !meshBindings.propertyExists(EnvironmentMappingProperties.ENVIRONMENT_MAP))
                return float4(0, 0, 0, 0);

			// compute reflected vector
			var cWorldCameraPosition	: SFloat = this.cameraPosition;
			var vsWorldVertexToCamera	: SFloat = normalize(subtract(cWorldCameraPosition, vsWorldPosition));
			var reflected				: SFloat = normalize(interpolate(reflect(vsWorldNormal.xyzz, vsWorldVertexToCamera.xyzz)));
			var reflectionType 			: int	 = meshBindings.getProperty(
				EnvironmentMappingProperties.ENVIRONMENT_MAPPING_TYPE
			);
            var reflectionMap           : SFloat    = getEnvironmentMap(reflectionType);

			// retrieve reflection color from reflection map
			var reflectionMapUV			: SFloat;
			var reflectionColor			: SFloat;

			switch (reflectionType)
			{
				case EnvironmentMappingType.NONE:
					reflectionColor = float4(0, 0, 0, 0);
					break;

				case EnvironmentMappingType.PROBE:
					reflectionMapUV = _probeProjectionPart.projectVector(reflected, new Rectangle(0, 0, 1, 1));
					reflectionColor = sampleTexture(reflectionMap, reflectionMapUV);
					break;

				case EnvironmentMappingType.BLINN_NEWELL:
					reflectionMapUV = _blinnNewellProjectionPart.projectVector(reflected, new Rectangle(0, 0, 1, 1));
					reflectionColor = sampleTexture(reflectionMap, reflectionMapUV);
					break;

				case EnvironmentMappingType.CUBE:
					reflectionColor = sampleTexture(reflectionMap, reflected);
					break;

				default:
					throw new Error('Unsupported reflection type');
			}

			// modifify alpha color
			if (meshBindings.propertyExists(EnvironmentMappingProperties.REFLECTIVITY))
			{
				var reflectivity : SFloat = meshBindings.getParameter(
					EnvironmentMappingProperties.REFLECTIVITY, 1
				);

				reflectionColor = float4(reflectionColor.xyz, multiply(reflectionColor.w, reflectivity));
			}

			return reflectionColor;
		}

        public function getEnvironmentMap(environmentMappingType : uint = 0) : SFloat
        {
            if (!environmentMappingType)
                meshBindings.getProperty(EnvironmentMappingProperties.ENVIRONMENT_MAPPING_TYPE);

            return meshBindings.getTextureParameter(
                EnvironmentMappingProperties.ENVIRONMENT_MAP,
                meshBindings.getProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_FILTERING, SamplerFiltering.NEAREST),
                meshBindings.getProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_MIPMAPPING, SamplerMipMapping.DISABLE),
                meshBindings.getProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_WRAPPING, SamplerWrapping.CLAMP),
                environmentMappingType == EnvironmentMappingType.CUBE ? SamplerDimension.CUBE : SamplerDimension.FLAT,
                meshBindings.getProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_FORMAT, SamplerFormat.RGBA)
            );
        }

		public function applyEnvironmentMapping(diffuse : SFloat) : SFloat
		{
			if (!meshBindings.propertyExists(EnvironmentMappingProperties.ENVIRONMENT_MAPPING_TYPE))
				return diffuse;

			return _blending.blend(
				getEnvironmentColor(),
				diffuse,
				meshBindings.getProperty(EnvironmentMappingProperties.ENVIRONMENT_BLENDING, Blending.ALPHA)
			);
		}
	}
}

package aerys.minko.render.shader.part.environment
{
	import flash.geom.Rectangle;

	import mx.messaging.SubscriptionInfo;

	import aerys.minko.render.material.environment.EnvironmentMappingProperties;
	import aerys.minko.render.shader.SFloat;
	import aerys.minko.render.shader.Shader;
	import aerys.minko.render.shader.part.BlendingShaderPart;
	import aerys.minko.render.shader.part.phong.LightAwareShaderPart;
	import aerys.minko.render.shader.part.projection.BlinnNewellProjectionShaderPart;
	import aerys.minko.render.shader.part.projection.ProbeProjectionShaderPart;
	import aerys.minko.type.enum.Blending;
	import aerys.minko.type.enum.EnvironmentMappingType;
	import aerys.minko.type.enum.SamplerDimension;
	import aerys.minko.type.enum.SamplerFiltering;
	import aerys.minko.type.enum.SamplerFormat;
	import aerys.minko.type.enum.SamplerMipMapping;
	import aerys.minko.type.enum.SamplerWrapping;

	public class EnvironmentMappingShaderPart extends LightAwareShaderPart
	{
		private var _blinnNewellProjectionPart	: BlinnNewellProjectionShaderPart;
		private var _probeProjectionPart		: ProbeProjectionShaderPart;
		private var _blending					: BlendingShaderPart;

		public function EnvironmentMappingShaderPart(main : Shader)
		{
			super(main);

			_blinnNewellProjectionPart	= new BlinnNewellProjectionShaderPart(main);
			_probeProjectionPart		= new ProbeProjectionShaderPart(main);
			_blending					= new BlendingShaderPart(main);
		}

		public function getEnvironmentColor() : SFloat
		{
            if (!meshBindings.propertyExists(EnvironmentMappingProperties.ENVIRONMENT_MAPPING_TYPE)
                || !meshBindings.propertyExists(EnvironmentMappingProperties.ENVIRONMENT_MAP))
                return float4(0, 0, 0, 0);

			// compute reflected vector
			var cWorldCameraPosition	: SFloat = this.cameraPosition;
			var vsWorldVertexToCamera	: SFloat = normalize(subtract(vsWorldPosition, cWorldCameraPosition));
			var reflected				: SFloat = normalize(interpolate(reflect(vsWorldVertexToCamera.xyzz, vsWorldNormal.xyzz)));
			var reflectionType 			: int	 = meshBindings.getProperty(
				EnvironmentMappingProperties.ENVIRONMENT_MAPPING_TYPE
			);
            var reflectionMap           : SFloat    = getEnvironmentMap(reflectionType);

			// retrieve reflection color from reflection map
			var reflectionMapUV			: SFloat;
			var reflectionColor			: SFloat;

			switch (reflectionType)
			{
				case EnvironmentMappingType.NONE:
					reflectionColor = float4(0, 0, 0, 0);
					break;

				case EnvironmentMappingType.PROBE:
					reflectionMapUV = _probeProjectionPart.projectVector(reflected, new Rectangle(0, 0, 1, 1));
					reflectionColor = sampleTexture(reflectionMap, reflectionMapUV);
					break;

				case EnvironmentMappingType.BLINN_NEWELL:
					reflectionMapUV = _blinnNewellProjectionPart.projectVector(reflected, new Rectangle(0, 0, 1, 1));
					reflectionColor = sampleTexture(reflectionMap, reflectionMapUV);
					break;

				case EnvironmentMappingType.CUBE:
					reflectionColor = sampleTexture(reflectionMap, reflected);
					break;

				default:
					throw new Error('Unsupported reflection type');
			}

			// modifify alpha color
			if (meshBindings.propertyExists(EnvironmentMappingProperties.REFLECTIVITY))
			{
				var reflectivity : SFloat = meshBindings.getParameter(
					EnvironmentMappingProperties.REFLECTIVITY, 1
				);

				reflectionColor = float4(reflectionColor.xyz, multiply(reflectionColor.w, reflectivity));
			}

			return reflectionColor;
		}

        public function getEnvironmentMap(environmentMappingType : uint = 0) : SFloat
        {
            if (!environmentMappingType)
                meshBindings.getProperty(EnvironmentMappingProperties.ENVIRONMENT_MAPPING_TYPE);

            return meshBindings.getTextureParameter(
                EnvironmentMappingProperties.ENVIRONMENT_MAP,
                meshBindings.getProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_FILTERING, SamplerFiltering.NEAREST),
                meshBindings.getProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_MIPMAPPING, SamplerMipMapping.DISABLE),
                meshBindings.getProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_WRAPPING, SamplerWrapping.CLAMP),
                environmentMappingType == EnvironmentMappingType.CUBE ? SamplerDimension.CUBE : SamplerDimension.FLAT,
                meshBindings.getProperty(EnvironmentMappingProperties.ENVIRONMENT_MAP_FORMAT, SamplerFormat.RGBA)
            );
        }

		public function applyEnvironmentMapping(diffuse : SFloat) : SFloat
		{
			if (!meshBindings.propertyExists(EnvironmentMappingProperties.ENVIRONMENT_MAPPING_TYPE))
				return diffuse;

			return _blending.blend(
				getEnvironmentColor(),
				diffuse,
				meshBindings.getProperty(EnvironmentMappingProperties.ENVIRONMENT_BLENDING, Blending.ALPHA)
			);
		}
	}
}

Fix env map computation

Fix env map computation


package aerys.minko.type.math
{
	import aerys.minko.type.Factory;

	public final class Quaternion
	{
		private static const FACTORY				: Factory			= Factory.getFactory(Quaternion);
		private static const EPSILON				: Number			= 1e-6;
		private static const TMP_QUATERNION			: Quaternion		= new Quaternion();

		private var _r		: Number	= 1.;
		private var _i		: Number	= 0.;
		private var _j		: Number	= 0.;
		private var _k		: Number	= 0.;

		final public function get r() : Number
		{
			return _r;
		}

		final public function get i() : Number
		{
			return _i;
		}

		final public function get j() : Number
		{
			return _j;
		}

		final public function get k() : Number
		{
			return _k;
		}

		public function get length() : Number
		{
			return Math.sqrt(_r * _r + _i * _i + _j * _j + _k * _k);
		}

		public function get norm() : Number
		{
			return length;
		}

		public static function add(q1 : Quaternion, q2 : Quaternion, out : Quaternion = null) : Quaternion
		{
			out ||= FACTORY.create() as Quaternion;
			out.copyFrom(q1)
			return out.incrementBy(q2);
		}

		public static function subtract(q1 : Quaternion, q2 : Quaternion, out : Quaternion = null) : Quaternion
		{
			out ||= FACTORY.create() as Quaternion;
			out.copyFrom(q1)
			return out.decrementBy(q2);
		}

		public static function scale(q : Quaternion, f : Number, out : Quaternion = null) : Quaternion
		{
			out ||= FACTORY.create() as Quaternion;
			out.copyFrom(q)
			return out.scaleBy(f);
		}

		public static function multiply(q1 : Quaternion, q2 : Quaternion, out : Quaternion = null) : Quaternion
		{
			out ||= FACTORY.create() as Quaternion;
			out.copyFrom(q1);
			return out.multiplyBy(q2);
		}

		public static function divide(q1 : Quaternion, q2 : Quaternion, out : Quaternion = null) : Quaternion
		{
			Quaternion.invert(q2, TMP_QUATERNION);
			Quaternion.multiply(q1, TMP_QUATERNION, out);
			return out;
		}

		public static function negate(q : Quaternion, out : Quaternion = null) : Quaternion
		{
			out ||= FACTORY.create() as Quaternion;
			out.copyFrom(q);
			return out.negate();
		}

		public static function conjugate(q : Quaternion, out : Quaternion = null) : Quaternion
		{
			out ||= FACTORY.create() as Quaternion;
			out.copyFrom(q);
			return out.conjugate();
		}

		public static function square(q : Quaternion, out : Quaternion = null) : Quaternion
		{
			out ||= FACTORY.create() as Quaternion;
			out.copyFrom(q);
			return out.square();
		}

		public static function invert(q : Quaternion, out : Quaternion = null) : Quaternion
		{
			out ||= FACTORY.create() as Quaternion;
			out.copyFrom(q);
			return out.invert();
		}

		public function Quaternion(r : Number = 0,
								   i : Number = 0,
								   j : Number = 0,
								   k : Number = 0)
		{
			_r = r;
			_i = i;
			_j = j;
			_k = k;
		}

		public function set(r : Number,
							i : Number,
							j : Number,
							k : Number) : Quaternion
		{
			_r = r;
			_i = i;
			_j = j;
			_k = k;

			return this;
		}

		public function copyFrom(q : Quaternion) : Quaternion
		{
			return set(q._r, q._i, q._j, q._k);
		}

		public function decrementBy(q : Quaternion) : Quaternion
		{
			_r += q._r;
			_i += q._i;
			_j += q._j;
			_k += q._k;

			return this;
		}

		public function incrementBy(q : Quaternion) : Quaternion
		{
			_r += q._r;
			_i += q._i;
			_j += q._j;
			_k += q._k;

			return this;
		}

		public function scaleBy(f : Number) : Quaternion
		{
			_r *= f;
			_i *= f;
			_j *= f;
			_k *= f;

			return this;
		}

		public function multiplyBy(q : Quaternion) : Quaternion
		{
			var t0 : Number = (_k - _j) * (q._j - q._k);
			var t1 : Number = (_r + _i) * (q._r + q._i);
			var t2 : Number = (_r - _i) * (q._j + q._k);
			var t3 : Number = (_k + _j) * (q._r - q._i);
			var t4 : Number = (_k - _i) * (q._i - q._j);
			var t5 : Number = (_k + _i) * (q._i + q._j);
			var t6 : Number = (_r + _j) * (q._r - q._k);
			var t7 : Number = (_r - _j) * (q._r + q._k);
			var t8 : Number = t5 + t6 + t7;
			var t9 : Number = (t4 + t8) / 2;

			_r = t0 + t9 - t5;
			_i = t1 + t9 - t8;
			_j = t2 + t9 - t7;
			_k = t3 + t9 - t6;

			return this;
		}

		public function normalize(q : Quaternion) : Quaternion
		{
			var l	: Number	= length;

			if (l != 0.)
			{
				_r *= l;
				_i *= l;
				_j *= l;
				_k *= l;
			}

			return this;
		}

		public function divide(q : Quaternion) : Quaternion
		{
			return Quaternion.divide(this, q, this);
		}

		public function negate() : Quaternion
		{
			return scaleBy(-1);
		}

		public function conjugate() : Quaternion
		{
			_i = -_i;
			_j = -_j;
			_k = -_k;

			return this;
		}

		public function square() : Quaternion
		{
			var tmp : Number = 2 * _r;

			_r = _r * _r - (_i * _i + _j * _j + _k * _k);
			_i = tmp * _i;
			_j = tmp * _j;
			_k = tmp * _k;

			return this;
		}

		public function invert() : Quaternion
		{
			var l : Number = length;

			_r /= l;
			_i /= -l;
			_j /= -l;
			_k /= -l;

			return this;
		}

		public function equals(q : Quaternion) : Boolean
		{
			return _r == q._r && _i == q._i && _j == q._j && _k == q._k;
		}

		public function clone() : Quaternion
		{
			return Quaternion(FACTORY.create()).set(_r, _i, _j, _k);
		}

		public function toString() : String
		{
			return '[Quaternion r="' + _r + '" i="' + _i + '" j="' + _j + '" k="' + _k + '"]';
		}

		public static function fromRotationBetweenVectors(u : Vector4, v : Vector4) : Quaternion
		{
			u.normalize();
			v.normalize();

			var kCosTheta		: Number	= Vector4.dotProduct(u, v)
			var k				: Number	= Math.sqrt(u.lengthSquared * v.lengthSquared);

			if (Math.abs(kCosTheta / k + 1) < EPSILON)
			{
				// 180 degree rotation around any orthogonal vector
				var other		: Vector4	= (Math.abs(Vector4.dotProduct(u, Vector4.X_AXIS)) < 1.0) ? Vector4.X_AXIS : Vector4.Y_AXIS;
				var axis		: Vector4	= Vector4.crossProduct(u, other).normalize();

				return fromRotationOnAxis(axis, Math.PI);
			}

			var c	: Vector4		= Vector4.crossProduct(u, v);
			var d	: Number		= Vector4.dotProduct(u, v);
			var q	: Quaternion	= Quaternion(FACTORY.create()).set(d + k, c.x, c.y, c.z);

			return q.scaleBy(1. / q.norm);
		}

		private static function fromRotationOnAxis(axis : Vector4, theta : Number) : Quaternion
		{
			theta *= .5;
			axis.normalize();

			var sine    : Number		= Math.sin(theta);

			var out		: Quaternion	= Quaternion(FACTORY.create()).set(
				Math.cos(theta),
				axis.x * sine,
				axis.y * sine,
				axis.z * sine
			);

			return out;
		}
	}
}

package aerys.minko.type.math
{
	import aerys.minko.type.Factory;

	public final class Quaternion
	{
		private static const FACTORY				: Factory			= Factory.getFactory(Quaternion);
		private static const EPSILON				: Number			= 1e-6;
		private static const TMP_QUATERNION			: Quaternion		= new Quaternion();

		private var _r		: Number	= 1.;
		private var _i		: Number	= 0.;
		private var _j		: Number	= 0.;
		private var _k		: Number	= 0.;

		final public function get r() : Number
		{
			return _r;
		}

		final public function get i() : Number
		{
			return _i;
		}

		final public function get j() : Number
		{
			return _j;
		}

		final public function get k() : Number
		{
			return _k;
		}

		public function get length() : Number
		{
			return Math.sqrt(_r * _r + _i * _i + _j * _j + _k * _k);
		}

		public function get norm() : Number
		{
			return length;
		}

		public static function add(q1 : Quaternion, q2 : Quaternion, out : Quaternion = null) : Quaternion
		{
			out ||= FACTORY.create() as Quaternion;
			out.copyFrom(q1)
			return out.incrementBy(q2);
		}

		public static function subtract(q1 : Quaternion, q2 : Quaternion, out : Quaternion = null) : Quaternion
		{
			out ||= FACTORY.create() as Quaternion;
			out.copyFrom(q1)
			return out.decrementBy(q2);
		}

		public static function scale(q : Quaternion, f : Number, out : Quaternion = null) : Quaternion
		{
			out ||= FACTORY.create() as Quaternion;
			out.copyFrom(q)
			return out.scaleBy(f);
		}

		public static function multiply(q1 : Quaternion, q2 : Quaternion, out : Quaternion = null) : Quaternion
		{
			out ||= FACTORY.create() as Quaternion;
			out.copyFrom(q1);
			return out.multiplyBy(q2);
		}

		public static function divide(q1 : Quaternion, q2 : Quaternion, out : Quaternion = null) : Quaternion
		{
			Quaternion.invert(q2, TMP_QUATERNION);
			Quaternion.multiply(q1, TMP_QUATERNION, out);
			return out;
		}

		public static function negate(q : Quaternion, out : Quaternion = null) : Quaternion
		{
			out ||= FACTORY.create() as Quaternion;
			out.copyFrom(q);
			return out.negate();
		}

		public static function conjugate(q : Quaternion, out : Quaternion = null) : Quaternion
		{
			out ||= FACTORY.create() as Quaternion;
			out.copyFrom(q);
			return out.conjugate();
		}

		public static function square(q : Quaternion, out : Quaternion = null) : Quaternion
		{
			out ||= FACTORY.create() as Quaternion;
			out.copyFrom(q);
			return out.square();
		}

		public static function invert(q : Quaternion, out : Quaternion = null) : Quaternion
		{
			out ||= FACTORY.create() as Quaternion;
			out.copyFrom(q);
			return out.invert();
		}

		public function Quaternion(r : Number = 0,
								   i : Number = 0,
								   j : Number = 0,
								   k : Number = 0)
		{
			_r = r;
			_i = i;
			_j = j;
			_k = k;
		}

		public function set(r : Number,
							i : Number,
							j : Number,
							k : Number) : Quaternion
		{
			_r = r;
			_i = i;
			_j = j;
			_k = k;

			return this;
		}

		public function copyFrom(q : Quaternion) : Quaternion
		{
			return set(q._r, q._i, q._j, q._k);
		}

		public function decrementBy(q : Quaternion) : Quaternion
		{
			_r += q._r;
			_i += q._i;
			_j += q._j;
			_k += q._k;

			return this;
		}

		public function incrementBy(q : Quaternion) : Quaternion
		{
			_r += q._r;
			_i += q._i;
			_j += q._j;
			_k += q._k;

			return this;
		}

		public function scaleBy(f : Number) : Quaternion
		{
			_r *= f;
			_i *= f;
			_j *= f;
			_k *= f;

			return this;
		}

		public function multiplyBy(q : Quaternion) : Quaternion
		{
			var t0 : Number = (_k - _j) * (q._j - q._k);
			var t1 : Number = (_r + _i) * (q._r + q._i);
			var t2 : Number = (_r - _i) * (q._j + q._k);
			var t3 : Number = (_k + _j) * (q._r - q._i);
			var t4 : Number = (_k - _i) * (q._i - q._j);
			var t5 : Number = (_k + _i) * (q._i + q._j);
			var t6 : Number = (_r + _j) * (q._r - q._k);
			var t7 : Number = (_r - _j) * (q._r + q._k);
			var t8 : Number = t5 + t6 + t7;
			var t9 : Number = (t4 + t8) / 2;

			_r = t0 + t9 - t5;
			_i = t1 + t9 - t8;
			_j = t2 + t9 - t7;
			_k = t3 + t9 - t6;

			return this;
		}

		public function normalize() : Quaternion
		{
			var l	: Number	= length;

			if (l != 0.)
			{
				_r *= l;
				_i *= l;
				_j *= l;
				_k *= l;
			}

			return this;
		}

		public function divide(q : Quaternion) : Quaternion
		{
			return Quaternion.divide(this, q, this);
		}

		public function negate() : Quaternion
		{
			return scaleBy(-1);
		}

		public function conjugate() : Quaternion
		{
			_i = -_i;
			_j = -_j;
			_k = -_k;

			return this;
		}

		public function square() : Quaternion
		{
			var tmp : Number = 2 * _r;

			_r = _r * _r - (_i * _i + _j * _j + _k * _k);
			_i = tmp * _i;
			_j = tmp * _j;
			_k = tmp * _k;

			return this;
		}

		public function invert() : Quaternion
		{
			var l : Number = length;

			_r /= l;
			_i /= -l;
			_j /= -l;
			_k /= -l;

			return this;
		}

		public function equals(q : Quaternion) : Boolean
		{
			return _r == q._r && _i == q._i && _j == q._j && _k == q._k;
		}

		public function clone() : Quaternion
		{
			return Quaternion(FACTORY.create()).set(_r, _i, _j, _k);
		}

		public function toString() : String
		{
			return '[Quaternion r="' + _r + '" i="' + _i + '" j="' + _j + '" k="' + _k + '"]';
		}

		public static function fromRotationBetweenVectors(u : Vector4, v : Vector4) : Quaternion
		{
			u.normalize();
			v.normalize();

			var kCosTheta		: Number	= Vector4.dotProduct(u, v)
			var k				: Number	= Math.sqrt(u.lengthSquared * v.lengthSquared);

			if (Math.abs(kCosTheta / k + 1) < EPSILON)
			{
				// 180 degree rotation around any orthogonal vector
				var other		: Vector4	= (Math.abs(Vector4.dotProduct(u, Vector4.X_AXIS)) < 1.0) ? Vector4.X_AXIS : Vector4.Y_AXIS;
				var axis		: Vector4	= Vector4.crossProduct(u, other).normalize();

				return fromRotationOnAxis(axis, Math.PI);
			}

			var c	: Vector4		= Vector4.crossProduct(u, v);
			var d	: Number		= Vector4.dotProduct(u, v);
			var q	: Quaternion	= Quaternion(FACTORY.create()).set(d + k, c.x, c.y, c.z);

			return q.scaleBy(1. / q.norm);
		}

		private static function fromRotationOnAxis(axis : Vector4, theta : Number) : Quaternion
		{
			theta *= .5;
			axis.normalize();

			var sine    : Number		= Math.sin(theta);

			var out		: Quaternion	= Quaternion(FACTORY.create()).set(
				Math.cos(theta),
				axis.x * sine,
				axis.y * sine,
				axis.z * sine
			);

			return out;
		}
	}
}

Remove unused argument to Quaternion.normalize().


package dolly {
import dolly.core.dolly_internal;
import dolly.data.CloneableClass;
import dolly.data.CompositeCloneableClass;

import mx.collections.ArrayCollection;
import mx.collections.ArrayList;

import org.as3commons.reflect.Field;
import org.as3commons.reflect.Type;
import org.flexunit.asserts.assertEquals;
import org.flexunit.asserts.assertFalse;
import org.flexunit.asserts.assertNotNull;
import org.flexunit.asserts.assertTrue;
import org.hamcrest.assertThat;
import org.hamcrest.collection.array;
import org.hamcrest.collection.arrayWithSize;
import org.hamcrest.collection.everyItem;
import org.hamcrest.core.isA;
import org.hamcrest.core.not;
import org.hamcrest.object.equalTo;

use namespace dolly_internal;

public class CloningOfCompositeCloneableClassTest {

	private var compositeCloneableClass:CompositeCloneableClass;
	private var compositeCloneableClassType:Type;

	[Before]
	public function before():void {
		compositeCloneableClass = new CompositeCloneableClass();

		const nestedCloneable:CloneableClass = new CloneableClass();
		nestedCloneable.property1 = "property1 value";
		nestedCloneable.writableField1 = "writableField1 value";

		const nestedCompositeCloneable:CompositeCloneableClass = new CompositeCloneableClass();
		nestedCompositeCloneable.compositeCloneable = compositeCloneableClass;
		nestedCompositeCloneable.array = [1, 2, 3];
		nestedCompositeCloneable.arrayList = new ArrayList([1, 2, 3]);
		nestedCompositeCloneable.arrayCollection = new ArrayCollection([1, 2, 3]);

		compositeCloneableClass.cloneable = nestedCloneable;
		compositeCloneableClass.compositeCloneable = nestedCompositeCloneable;
		compositeCloneableClass.array = [1, 2, 3, 4, 5];
		compositeCloneableClass.arrayList = new ArrayList([1, 2, 3, 4, 5]);
		compositeCloneableClass.arrayCollection = new ArrayCollection([1, 2, 3, 4, 5]);

		compositeCloneableClassType = Type.forInstance(compositeCloneableClass);
	}

	[After]
	public function after():void {
		compositeCloneableClass.compositeCloneable =
				compositeCloneableClass.compositeCloneable.compositeCloneable = null;
		compositeCloneableClass.cloneable = null;
		compositeCloneableClass = null;
		compositeCloneableClassType = null;
	}

	[Test]
	public function findingAllWritableFieldsForType():void {
		const writableFields:Vector.<Field> = Cloner.findAllWritableFieldsForType(compositeCloneableClassType);
		assertNotNull(writableFields);
		assertEquals(5, writableFields.length);
	}

	[Test]
	public function cloningOfArray():void {
		const clone:CompositeCloneableClass = Cloner.clone(compositeCloneableClass);

		assertNotNull(clone.array);
		assertThat(clone.array, arrayWithSize(5));
		assertThat(clone.array, compositeCloneableClass.array);
		assertFalse(clone.array == compositeCloneableClass.array);
		assertThat(clone.array, everyItem(isA(Number)));
		assertThat(clone.array, array(equalTo(1), equalTo(2), equalTo(3), equalTo(4), equalTo(5)));
	}

	[Test]
	public function cloningOfArrayList():void {
		const clone:CompositeCloneableClass = Cloner.clone(compositeCloneableClass);

		const arrayList:ArrayList = clone.arrayList;

		assertNotNull(arrayList);
		assertFalse(clone.arrayList == compositeCloneableClass.arrayList);
		assertEquals(arrayList.length, 5);
		assertEquals(arrayList.getItemAt(0), 1);
		assertEquals(arrayList.getItemAt(1), 2);
		assertEquals(arrayList.getItemAt(2), 3);
		assertEquals(arrayList.getItemAt(3), 4);
		assertEquals(arrayList.getItemAt(4), 5);
	}

	[Test]
	public function cloningOfArrayCollection():void {
		const clone:CompositeCloneableClass = Cloner.clone(compositeCloneableClass);

		const arrayCollection:ArrayCollection = clone.arrayCollection;

		assertNotNull(arrayCollection);
		assertFalse(clone.arrayCollection == compositeCloneableClass.arrayCollection);
		assertEquals(arrayCollection.length, 5);
		assertEquals(arrayCollection.getItemAt(0), 1);
		assertEquals(arrayCollection.getItemAt(1), 2);
		assertEquals(arrayCollection.getItemAt(2), 3);
		assertEquals(arrayCollection.getItemAt(3), 4);
		assertEquals(arrayCollection.getItemAt(4), 5);
	}

	[Test]
	public function cloningOfCloneableProperty():void {
		const clone:CompositeCloneableClass = Cloner.clone(compositeCloneableClass);

		const cloneable:CloneableClass = clone.cloneable;

		assertNotNull(cloneable);
		assertThat(cloneable, isA(CloneableClass));
		assertEquals(cloneable.property1, "property1 value");
		assertEquals(cloneable.writableField1, "writableField1 value");
		assertThat(cloneable, not(compositeCloneableClass.cloneable));
	}

	[Test]
	public function cloningOfCompositeCloneableClass():void {
		const clone:CompositeCloneableClass = Cloner.clone(compositeCloneableClass);

		const compositeCloneable:CompositeCloneableClass = clone.compositeCloneable;

		assertNotNull(compositeCloneable);
		assertThat(compositeCloneable, isA(CompositeCloneableClass));

		assertNotNull(compositeCloneable.array);
		assertThat(compositeCloneable.array, arrayWithSize(3));
		assertThat(compositeCloneable.array, everyItem(isA(Number)));
		assertThat(compositeCloneable.array, array(equalTo(1), equalTo(2), equalTo(3)));

		assertNotNull(compositeCloneable.arrayList);
		assertThat(compositeCloneable.arrayList, isA(ArrayList));
		assertEquals(compositeCloneable.arrayList.length, 3);
		assertEquals(compositeCloneable.arrayList.getItemAt(0), 1);
		assertEquals(compositeCloneable.arrayList.getItemAt(1), 2);
		assertEquals(compositeCloneable.arrayList.getItemAt(2), 3);

		assertNotNull(compositeCloneable.arrayCollection);
		assertThat(compositeCloneable.arrayCollection, isA(ArrayCollection));
		assertEquals(compositeCloneable.arrayCollection.length, 3);
		assertEquals(compositeCloneable.arrayCollection.getItemAt(0), 1);
		assertEquals(compositeCloneable.arrayCollection.getItemAt(1), 2);
		assertEquals(compositeCloneable.arrayCollection.getItemAt(2), 3);

		assertNotNull(compositeCloneable.compositeCloneable);
		assertThat(compositeCloneable.compositeCloneable, isA(CompositeCloneableClass));
		assertEquals(clone, compositeCloneable.compositeCloneable);
		assertEquals(clone.array, compositeCloneable.compositeCloneable.array);
		assertEquals(clone.arrayList, compositeCloneable.compositeCloneable.arrayList);
		assertEquals(clone.arrayCollection, compositeCloneable.compositeCloneable.arrayCollection);
		assertEquals(clone.cloneable, compositeCloneable.compositeCloneable.cloneable);
	}
}
}

package dolly {
import dolly.core.dolly_internal;
import dolly.data.CloneableClass;
import dolly.data.CompositeCloneableClass;

import mx.collections.ArrayCollection;
import mx.collections.ArrayList;

import org.as3commons.reflect.Field;
import org.as3commons.reflect.Type;
import org.flexunit.asserts.assertEquals;
import org.flexunit.asserts.assertFalse;
import org.flexunit.asserts.assertNotNull;
import org.hamcrest.assertThat;
import org.hamcrest.collection.array;
import org.hamcrest.collection.arrayWithSize;
import org.hamcrest.collection.everyItem;
import org.hamcrest.core.isA;
import org.hamcrest.core.not;
import org.hamcrest.object.equalTo;

use namespace dolly_internal;

public class CloningOfCompositeCloneableClassTest {

	private var compositeCloneableClass:CompositeCloneableClass;
	private var compositeCloneableClassType:Type;

	[Before]
	public function before():void {
		compositeCloneableClass = new CompositeCloneableClass();

		const nestedCloneable:CloneableClass = new CloneableClass();
		nestedCloneable.property1 = "property1 value";
		nestedCloneable.writableField1 = "writableField1 value";

		const nestedCompositeCloneable:CompositeCloneableClass = new CompositeCloneableClass();
		nestedCompositeCloneable.compositeCloneable = compositeCloneableClass;
		nestedCompositeCloneable.array = [1, 2, 3];
		nestedCompositeCloneable.arrayList = new ArrayList([1, 2, 3]);
		nestedCompositeCloneable.arrayCollection = new ArrayCollection([1, 2, 3]);

		compositeCloneableClass.cloneable = nestedCloneable;
		compositeCloneableClass.compositeCloneable = nestedCompositeCloneable;
		compositeCloneableClass.array = [1, 2, 3, 4, 5];
		compositeCloneableClass.arrayList = new ArrayList([1, 2, 3, 4, 5]);
		compositeCloneableClass.arrayCollection = new ArrayCollection([1, 2, 3, 4, 5]);

		compositeCloneableClassType = Type.forInstance(compositeCloneableClass);
	}

	[After]
	public function after():void {
		compositeCloneableClass.compositeCloneable =
				compositeCloneableClass.compositeCloneable.compositeCloneable = null;
		compositeCloneableClass.cloneable = null;
		compositeCloneableClass = null;
		compositeCloneableClassType = null;
	}

	[Test]
	public function findingAllWritableFieldsForType():void {
		const writableFields:Vector.<Field> = Cloner.findAllWritableFieldsForType(compositeCloneableClassType);
		assertNotNull(writableFields);
		assertEquals(5, writableFields.length);
	}

	[Test]
	public function cloningOfArray():void {
		const clone:CompositeCloneableClass = Cloner.clone(compositeCloneableClass);

		assertNotNull(clone.array);
		assertThat(clone.array, arrayWithSize(5));
		assertThat(clone.array, compositeCloneableClass.array);
		assertFalse(clone.array == compositeCloneableClass.array);
		assertThat(clone.array, everyItem(isA(Number)));
		assertThat(clone.array, array(equalTo(1), equalTo(2), equalTo(3), equalTo(4), equalTo(5)));
	}

	[Test]
	public function cloningOfArrayList():void {
		const clone:CompositeCloneableClass = Cloner.clone(compositeCloneableClass);

		const arrayList:ArrayList = clone.arrayList;

		assertNotNull(arrayList);
		assertFalse(clone.arrayList == compositeCloneableClass.arrayList);
		assertEquals(arrayList.length, 5);
		assertEquals(arrayList.getItemAt(0), 1);
		assertEquals(arrayList.getItemAt(1), 2);
		assertEquals(arrayList.getItemAt(2), 3);
		assertEquals(arrayList.getItemAt(3), 4);
		assertEquals(arrayList.getItemAt(4), 5);
	}

	[Test]
	public function cloningOfArrayCollection():void {
		const clone:CompositeCloneableClass = Cloner.clone(compositeCloneableClass);

		const arrayCollection:ArrayCollection = clone.arrayCollection;

		assertNotNull(arrayCollection);
		assertFalse(clone.arrayCollection == compositeCloneableClass.arrayCollection);
		assertEquals(arrayCollection.length, 5);
		assertEquals(arrayCollection.getItemAt(0), 1);
		assertEquals(arrayCollection.getItemAt(1), 2);
		assertEquals(arrayCollection.getItemAt(2), 3);
		assertEquals(arrayCollection.getItemAt(3), 4);
		assertEquals(arrayCollection.getItemAt(4), 5);
	}

	[Test]
	public function cloningOfCloneableProperty():void {
		const clone:CompositeCloneableClass = Cloner.clone(compositeCloneableClass);

		const cloneable:CloneableClass = clone.cloneable;

		assertNotNull(cloneable);
		assertThat(cloneable, isA(CloneableClass));
		assertEquals(cloneable.property1, "property1 value");
		assertEquals(cloneable.writableField1, "writableField1 value");
		assertThat(cloneable, not(compositeCloneableClass.cloneable));
	}

	[Test]
	public function cloningOfCompositeCloneableClass():void {
		const clone:CompositeCloneableClass = Cloner.clone(compositeCloneableClass);

		const compositeCloneable:CompositeCloneableClass = clone.compositeCloneable;

		assertNotNull(compositeCloneable);
		assertThat(compositeCloneable, isA(CompositeCloneableClass));

		assertNotNull(compositeCloneable.array);
		assertThat(compositeCloneable.array, arrayWithSize(3));
		assertThat(compositeCloneable.array, everyItem(isA(Number)));
		assertThat(compositeCloneable.array, array(equalTo(1), equalTo(2), equalTo(3)));

		assertNotNull(compositeCloneable.arrayList);
		assertThat(compositeCloneable.arrayList, isA(ArrayList));
		assertEquals(compositeCloneable.arrayList.length, 3);
		assertEquals(compositeCloneable.arrayList.getItemAt(0), 1);
		assertEquals(compositeCloneable.arrayList.getItemAt(1), 2);
		assertEquals(compositeCloneable.arrayList.getItemAt(2), 3);

		assertNotNull(compositeCloneable.arrayCollection);
		assertThat(compositeCloneable.arrayCollection, isA(ArrayCollection));
		assertEquals(compositeCloneable.arrayCollection.length, 3);
		assertEquals(compositeCloneable.arrayCollection.getItemAt(0), 1);
		assertEquals(compositeCloneable.arrayCollection.getItemAt(1), 2);
		assertEquals(compositeCloneable.arrayCollection.getItemAt(2), 3);

		assertNotNull(compositeCloneable.compositeCloneable);
		assertThat(compositeCloneable.compositeCloneable, isA(CompositeCloneableClass));
		assertEquals(clone, compositeCloneable.compositeCloneable);
		assertEquals(clone.array, compositeCloneable.compositeCloneable.array);
		assertEquals(clone.arrayList, compositeCloneable.compositeCloneable.arrayList);
		assertEquals(clone.arrayCollection, compositeCloneable.compositeCloneable.arrayCollection);
		assertEquals(clone.cloneable, compositeCloneable.compositeCloneable.cloneable);
	}
}
}

Optimize imports.

Optimize imports.