 		{
 			super(Mesh);
 			
+			_method				= method;
+			_skeletonRoot		= skeletonRoot;
+			_bindShapeMatrix	= bindShape.minko_math::_matrix;
+			_isDirty			= false;
+			
+			initialize(joints, invBindMatrices);
+		}
+		
+		private function initialize(joints			: Vector.<Group>,
+									invBindMatrices	: Vector.<Matrix4x4>) : void
+		{
 			var numJoints : uint = joints.length;
 			
-			_method			 	= method;
-			_skeletonRoot		= skeletonRoot;
-			_joints				= joints.slice();
-			_bindShape			= bindShape.minko_math::_matrix;
+			_joints	= joints.slice();
+			
 			_invBindMatrices	= new Vector.<Matrix3D>(numJoints, true);
-			_isDirty			= false;
-			
 			for (var jointId : uint = 0; jointId < numJoints; ++jointId)
 				_invBindMatrices[jointId] = invBindMatrices[jointId].minko_math::_matrix;
 			
-			init();
-		}
-		
-		private function init() : void
-		{
 			if (skinningMethod == SkinningMethod.SOFTWARE_MATRIX)
-				_skinningHelper = new SoftwareSkinningHelper(_method, _bindShape, _invBindMatrices);
+				_skinningHelper = new SoftwareSkinningHelper(_method, _bindShapeMatrix, _invBindMatrices);
 			else
-				_skinningHelper = new ShaderSkinningHelper(_method, _bindShape, _invBindMatrices);
-		}
-		
-		override protected function targetAddedHandler(ctrl		: EnterFrameController,
-													   target	: ISceneNode) : void
-		{
-			super.targetAddedHandler(ctrl, target);
-			
-			if (numTargets == 1)
+				_skinningHelper = new ShaderSkinningHelper(_method, _bindShapeMatrix, _invBindMatrices);
+		}
+		
+		override protected function targetAddedToSceneHandler(target	: ISceneNode,
+															  scene		: Scene) : void
+		{
+			super.targetAddedToSceneHandler(target, scene);
+			
+			if (numTargetsInScene == 1)
 				subscribeToJoints();
 			
+			var mesh : Mesh = target as Mesh;
+			
+			mesh.bindings.addCallback('inFrustum', meshVisibilityChangedHandler);
+			_skinningHelper.addMesh(mesh);
+			
 			_isDirty = true;
-			_skinningHelper.addMesh(target as Mesh);
-		}
-		
-		override protected function targetRemovedHandler(ctrl	: EnterFrameController,
-														 target	: ISceneNode) : void
-		{
-			super.targetRemovedHandler(ctrl, target);
+		}
+		
+		override protected function targetRemovedFromSceneHandler(target	: ISceneNode,
+																  scene		: Scene) : void
+		{
+			super.targetRemovedFromSceneHandler(target, scene);
 			
 			if (numTargets == 0)
 				unsubscribeFromJoints();
 			
-			_skinningHelper.removeMesh(target as Mesh);
+			var mesh : Mesh = target as Mesh;
+			
+			mesh.bindings.removeCallback('inFrustum', meshVisibilityChangedHandler);
+			_skinningHelper.removeMesh(mesh);
 		}
 		
 		private function jointLocalToWorldChangedHandler(emitter : Matrix4x4) : void

														   destination	: BitmapData, 
														   time			: Number) : void
		{
			if (_isDirty)
			{
				_skinningHelper.update(_skeletonRoot, _joints);
				_isDirty = false;

		{
			return new SkinningController(_method, _skeletonRoot, _joints, bindShape, invBindMatrices);
		}
		
		private function meshVisibilityChangedHandler(bindings 	: DataBindings,
												  property	: String,
												  oldValue	: Boolean,
												  newValue	: Boolean) : void
		{
			if (newValue)
				_skinningHelper.addMesh(bindings.owner as Mesh);
			else
				_skinningHelper.removeMesh(bindings.owner as Mesh);
		}
	}
}
