/**
	 * @return Box in light space containing shadow caster and receiver (scene dependent)
	 */
	AABBox<float> ShadowManager::createSceneDependentBox(const AABBox<float> &aabboxSceneIndependent, const OBBox<float> &obboxSceneIndependentViewSpace,
			const std::set<Model *> &models, const Matrix4<float> &lightViewMatrix) const
	{
		AABBox<float> aabboxSceneDependent;
		bool boxInitialized = false;

		AABBox<float> aabboxSceneIndependentViewSpace = obboxSceneIndependentViewSpace.toAABBox();

		for(std::set<Model *>::iterator it = models.begin(); it!=models.end(); ++it)
		{
			const Model* model = *it;
			if(model->isProduceShadow())
			{
				const std::vector<AABBox<float>> &splittedAABBox = model->getSplittedAABBox();
				for(unsigned int i=0; i<splittedAABBox.size(); ++i)
				{
					if(splittedAABBox.size()==1 || obboxSceneIndependentViewSpace.collideWithAABBox(splittedAABBox[i]))
					{
						if(boxInitialized)
						{
							aabboxSceneDependent = aabboxSceneDependent.merge(lightViewMatrix * splittedAABBox[i]);
						}else
						{
							aabboxSceneDependent = lightViewMatrix * splittedAABBox[i];
							boxInitialized = true;
						}
					}
				}
			}
		}

		Point3<float> cutMin(
			aabboxSceneDependent.getMin().X<aabboxSceneIndependent.getMin().X ? aabboxSceneIndependent.getMin().X : aabboxSceneDependent.getMin().X,
			aabboxSceneDependent.getMin().Y<aabboxSceneIndependent.getMin().Y ? aabboxSceneIndependent.getMin().Y : aabboxSceneDependent.getMin().Y,
			aabboxSceneIndependent.getMin().Z); //shadow can be projected outside the box: value cannot be capped

		Point3<float> cutMax(
			aabboxSceneDependent.getMax().X>aabboxSceneIndependent.getMax().X ? aabboxSceneIndependent.getMax().X : aabboxSceneDependent.getMax().X,
			aabboxSceneDependent.getMax().Y>aabboxSceneIndependent.getMax().Y ? aabboxSceneIndependent.getMax().Y : aabboxSceneDependent.getMax().Y,
			aabboxSceneDependent.getMax().Z>aabboxSceneIndependent.getMax().Z ? aabboxSceneIndependent.getMax().Z : aabboxSceneDependent.getMax().Z);

		cutMin.X = (cutMin.X<0.0f) ? cutMin.X-(lightViewOverflowStepSize+fmod(cutMin.X, lightViewOverflowStepSize)) : cutMin.X-fmod(cutMin.X, lightViewOverflowStepSize);
		cutMin.Y = (cutMin.Y<0.0f) ? cutMin.Y-(lightViewOverflowStepSize+fmod(cutMin.Y, lightViewOverflowStepSize)) : cutMin.Y-fmod(cutMin.Y, lightViewOverflowStepSize);
		cutMin.Z = (cutMin.Z<0.0f) ? cutMin.Z-(lightViewOverflowStepSize+fmod(cutMin.Z, lightViewOverflowStepSize)) : cutMin.Z-fmod(cutMin.Z, lightViewOverflowStepSize);
		cutMax.X = (cutMax.X<0.0f) ? cutMax.X-fmod(cutMax.X, lightViewOverflowStepSize) : cutMax.X+(lightViewOverflowStepSize-fmod(cutMax.X, lightViewOverflowStepSize));
		cutMax.Y = (cutMax.Y<0.0f) ? cutMax.Y-fmod(cutMax.Y, lightViewOverflowStepSize) : cutMax.Y+(lightViewOverflowStepSize-fmod(cutMax.Y, lightViewOverflowStepSize));
		cutMax.Z = (cutMax.Z<0.0f) ? cutMax.Z-fmod(cutMax.Z, lightViewOverflowStepSize) : cutMax.Z+(lightViewOverflowStepSize-fmod(cutMax.Z, lightViewOverflowStepSize));

		return AABBox<float>(cutMin, cutMax);
	}
	AABBox<float> CollisionCompoundShape::toAABBox(const PhysicsTransform &physicsTransform) const
	{
		Point3<float> rotatedTranslation = physicsTransform.getOrientation().rotatePoint(Point3<float>(localizedShapes[0]->translation));
		Point3<float> finalPosition = physicsTransform.getPosition().translate(rotatedTranslation.toVector());
		PhysicsTransform shapeWorldTransform(finalPosition, physicsTransform.getOrientation());
		AABBox<float> globalCompoundBox = localizedShapes[0]->shape->toAABBox(shapeWorldTransform);

		for(unsigned int i=1; i<localizedShapes.size(); ++i)
		{
			rotatedTranslation = physicsTransform.getOrientation().rotatePoint(Point3<float>(localizedShapes[i]->translation));
			finalPosition = physicsTransform.getPosition().translate(rotatedTranslation.toVector());
			shapeWorldTransform.setPosition(finalPosition);

			AABBox<float> compoundBox = localizedShapes[i]->shape->toAABBox(shapeWorldTransform);

			globalCompoundBox = globalCompoundBox.merge(compoundBox);
		}

		return globalCompoundBox;
	}