bool FrustumShadowData::areIdenticalAABBox(const AABBox<float> &shadowCasterReceiverBox1, const AABBox<float> &shadowCasterReceiverBox2) const
	{
		constexpr float SQUARE_EPSILON = 0.0001f * 0.0001f;

		return shadowCasterReceiverBox1.getMin().squareDistance(shadowCasterReceiverBox2.getMin())<SQUARE_EPSILON
				&& shadowCasterReceiverBox1.getMax().squareDistance(shadowCasterReceiverBox2.getMax())<SQUARE_EPSILON;
	}
	/**
	 * Split the bounding box in several bounding boxes at limitSize.
	 * If original box doesn't exceed limit size, the original box is returned.
	 */
	std::vector<AABBox<float>> SplitBoundingBox::split(const AABBox<float> &aabbox) const
	{
		std::vector<float> axisSplits[3];
		for(unsigned int axis=0; axis<3; ++axis)
		{
			float size = aabbox.getHalfSize(axis) * 2.0f;
			axisSplits[axis].push_back(aabbox.getMin()[axis]);

			auto nbSplits = static_cast<int>(std::ceil(size/limitSize));
			float maxValue = aabbox.getMax()[axis];

			for(int split = 0; split < nbSplits; ++split)
			{
				float splitValue = std::min(aabbox.getMin()[axis] + limitSize*(split+1), maxValue);
				axisSplits[axis].push_back(splitValue);
			}
		}

		std::vector<AABBox<float>> splittedBoundingBox;
		for(unsigned int x=1; x<axisSplits[0].size(); ++x)
		{
			for(unsigned int y=1; y<axisSplits[1].size(); ++y)
			{
				for(unsigned int z=1; z<axisSplits[2].size(); ++z)
				{
					Point3<float> minPoint(axisSplits[0][x-1], axisSplits[1][y-1], axisSplits[2][z-1]);
					Point3<float> maxPoint(axisSplits[0][x], axisSplits[1][y], axisSplits[2][z]);

					splittedBoundingBox.emplace_back(AABBox<float>(minPoint, maxPoint));
				}
			}
		}

		return splittedBoundingBox;
	}
Beispiel #3
0
	/**
	* @return True if the bounding box collides or is inside this frustum
	*/
	template<class T> bool Frustum<T>::collideWithAABBox(const AABBox<T> &bbox) const
	{
		for (auto &plane : planes)
		{
			const Vector3<T> &normal = plane.getNormal();

			Point3<T> nVertex(bbox.getMax());
			if(normal.X >= 0.0)
			{
				nVertex.X = bbox.getMin().X;
			}
			if(normal.Y >= 0.0)
			{
				nVertex.Y = bbox.getMin().Y;
			}
			if(normal.Z >= 0.0)
			{
				nVertex.Z = bbox.getMin().Z;
			}

			if (plane.distance(nVertex) > 0.0)
			{
				return false;
			}
		}

		return true;
	}
Beispiel #4
0
	void AABBNode::updateAABBox(float fatMargin)
	{
		if (isLeaf())
		{
			Point3<float> fatMargin3(fatMargin, fatMargin, fatMargin);
			AABBox<float> bodyBox = bodyNodeData->retrieveBodyAABBox();

			aabbox = AABBox<float>(bodyBox.getMin()-fatMargin3, bodyBox.getMax()+fatMargin3);
		}else
		{
			aabbox = children[0]->getAABBox().merge(children[1]->getAABBox());
		}
	}
void ShapeToAABBoxTest::boxConversion()
{
	CollisionBoxShape collisionBox(Vector3<float>(1.0, 2.0, 1.0)); //box 1x2x1
	PhysicsTransform transform(urchin::Point3<float>(0.0, 0.0, 0.0), //move 0 unit on X, Y and Z axis
			urchin::Quaternion<float>(urchin::Vector3<float>(0.0, 0.0, 1.0), 3.14159265358979/4)); //rotate 45° on Z axis

	AABBox<float> box = collisionBox.toAABBox(transform);

	AssertHelper::assertFloatEquals(box.getHalfSize(0), 2.12132034356);
	AssertHelper::assertFloatEquals(box.getHalfSize(1), 2.12132034356);
	AssertHelper::assertFloatEquals(box.getHalfSize(2), 1.0);
	AssertHelper::assertPoint3FloatEquals(box.getMin(), Point3<float>(-2.12132034356, -2.12132034356, -1.0));
	AssertHelper::assertPoint3FloatEquals(box.getMax(), Point3<float>(2.12132034356, 2.12132034356, 1.0));
}
	/**
	 * @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);
	}
void ShapeToAABBoxTest::convexHullConversion()
{
	Point3<float> boxPointsTab[] = {
			Point3<float>(-1.0, -2.0, 1.0), Point3<float>(1.0, -2.0, 1.0), Point3<float>(1.0, 2.0, 1.0), Point3<float>(-1.0, 2.0, 1.0),
			Point3<float>(-1.0, -2.0, -1.0), Point3<float>(1.0, -2.0, -1.0), Point3<float>(1.0, 2.0, -1.0), Point3<float>(-1.0, 2.0, -1.0),
	};
	std::vector<Point3<float>> boxPoints(boxPointsTab, boxPointsTab+sizeof(boxPointsTab)/sizeof(Point3<float>));

	CollisionConvexHullShape collisionConvexHull(0.0, boxPoints);
	PhysicsTransform transform(urchin::Point3<float>(0.0, 0.0, 0.0), //move 0 unit on X, Y and Z axis
			urchin::Quaternion<float>(urchin::Vector3<float>(0.0, 0.0, 1.0), -3.14159265358979/4)); //rotate 45° on Z axis

	AABBox<float> box = collisionConvexHull.toAABBox(transform);

	AssertHelper::assertFloatEquals(box.getHalfSize(0), 2.12132034356);
	AssertHelper::assertFloatEquals(box.getHalfSize(1), 2.12132034356);
	AssertHelper::assertFloatEquals(box.getHalfSize(2), 1.0);
	AssertHelper::assertPoint3FloatEquals(box.getMin(), Point3<float>(-2.12132034356, -2.12132034356, -1.0));
	AssertHelper::assertPoint3FloatEquals(box.getMax(), Point3<float>(2.12132034356, 2.12132034356, 1.0));
}