void COctreeTriangleSelector::getTrianglesFromOctree(
		SOctreeNode* node, s32& trianglesWritten,
		s32 maximumSize, const core::aabbox3d<f32>& box,
		const core::matrix4* mat, core::triangle3df* triangles) const
{
	if (!box.intersectsWithBox(node->Box))
		return;

	const u32 cnt = node->Triangles.size();

	for (u32 i=0; i<cnt; ++i)
	{
		const core::triangle3df& srcTri = node->Triangles[i];
		// This isn't an accurate test, but it's fast, and the 
		// API contract doesn't guarantee complete accuracy.
		if (srcTri.isTotalOutsideBox(box))
			continue;

		core::triangle3df& dstTri = triangles[trianglesWritten];
		mat->transformVect(dstTri.pointA, srcTri.pointA );
		mat->transformVect(dstTri.pointB, srcTri.pointB );
		mat->transformVect(dstTri.pointC, srcTri.pointC );
		++trianglesWritten;

		// Halt when the out array is full.
		if (trianglesWritten == maximumSize)
			return;
	}

	for (u32 i=0; i<8; ++i)
		if (node->Child[i])
			getTrianglesFromOctree(node->Child[i], trianglesWritten,
			maximumSize, box, mat, triangles);
}
//! Gets all triangles which lie within a specific bounding box.
void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles,
					s32 arraySize, s32& outTriangleCount,
					const core::aabbox3d<f32>& box,
					const core::matrix4* transform) const
{
	core::matrix4 mat(core::matrix4::EM4CONST_NOTHING);
	core::aabbox3d<f32> invbox = box;

	if (SceneNode)
	{
		SceneNode->getAbsoluteTransformation().getInverse(mat);
		mat.transformBoxEx(invbox);
	}

	if (transform)
		mat = *transform;
	else
		mat.makeIdentity();

	if (SceneNode)
		mat *= SceneNode->getAbsoluteTransformation();

	s32 trianglesWritten = 0;

	if (Root)
		getTrianglesFromOctree(Root, trianglesWritten,
			arraySize, invbox, &mat, triangles);

	outTriangleCount = trianglesWritten;
}
	//! Gets all triangles which lie within a specific bounding box.
	void COctreeTriangleSelector::getTriangles(triangle3df* triangles,
		SINT32 arraySize, SINT32& outTriangleCount,
		const AxisAlignedBox& box,
		const Matrix4* transform) const
	{
		Matrix4 mat(Matrix4::ZERO);
		AxisAlignedBox invbox = box;

		if (SceneNode)
		{
			//SceneNode->getAbsoluteTransformation().getInverse(mat);
			mat = SceneNode->getAbsoluteTransformation();
			mat.inverse();
			//mat.transformBoxEx(invbox);
			invbox.transform(mat);
		}

		if (transform)
			mat = *transform;
		else
			mat = Matrix4::IDENTITY;

		if (SceneNode)
			//mat *= SceneNode->getAbsoluteTransformation();
			mat = SceneNode->getAbsoluteTransformation() * mat;

		SINT32 trianglesWritten = 0;

		if (Root)
			getTrianglesFromOctree(Root, trianglesWritten,
			arraySize, invbox, &mat, triangles);

		outTriangleCount = trianglesWritten;
	}
void COctreeTriangleSelector::getTrianglesFromOctree(
		SOctreeNode* node, s32& trianglesWritten,
		s32 maximumSize, const core::aabbox3d<f32>& box,
		const core::matrix4* mat, core::triangle3df* triangles) const
{
	if (!box.intersectsWithBox(node->Box))
		return;

	s32 cnt = node->Triangles.size();
	if (cnt + trianglesWritten > maximumSize)
		cnt -= cnt + trianglesWritten - maximumSize;

	s32 i;

	for (i=0; i<cnt; ++i)
	{
		mat->transformVect(triangles[trianglesWritten].pointA, node->Triangles[i].pointA );
		mat->transformVect(triangles[trianglesWritten].pointB, node->Triangles[i].pointB );
		mat->transformVect(triangles[trianglesWritten].pointC, node->Triangles[i].pointC );
		++trianglesWritten;
	}

	for (i=0; i<8; ++i)
		if (node->Child[i])
			getTrianglesFromOctree(node->Child[i], trianglesWritten,
			maximumSize, box, mat, triangles);
}
	//! Gets all triangles which have or may have contact with a 3d line.
	// new version: from user Piraaate
	void COctreeTriangleSelector::getTriangles(triangle3df* triangles, SINT32 arraySize,
		SINT32& outTriangleCount, const line3df& line,
		const Matrix4* transform) const
	{
#if 0
		AxisAlignedBox box(line.start);
		box.addInternalPoint(line.end);

		// TODO: Could be optimized for line a little bit more.
		COctreeTriangleSelector::getTriangles(triangles, arraySize, outTriangleCount,
			box, transform);
#else

		Matrix4 mat(Matrix4::ZERO);

		Vector3 vectStartInv(line.start), vectEndInv(line.end);
		if (SceneNode)
		{
			mat = SceneNode->getAbsoluteTransformation();
			//mat.makeInverse();
			mat = Matrix4::IDENTITY;
			//mat.transformVect(vectStartInv, line.start);
			//mat.transformVect(vectEndInv, line.end);
			vectStartInv = mat.transformAffine(line.start);
			vectEndInv = mat.transformAffine(line.end);
		}
		line3d<FLOAT32> invline(vectStartInv, vectEndInv);

		//mat.makeIdentity();
		mat = Matrix4::IDENTITY;

		if (transform)
			mat = (*transform);

		if (SceneNode)
			mat = SceneNode->getAbsoluteTransformation() * mat;//mat *= SceneNode->getAbsoluteTransformation();

		SINT32 trianglesWritten = 0;

		if (Root)
			getTrianglesFromOctree(Root, trianglesWritten, arraySize, invline, &mat, triangles);

		outTriangleCount = trianglesWritten;
#endif
	}
//! Gets all triangles which have or may have contact with a 3d line.
// new version: from user Piraaate
void COctreeTriangleSelector::getTriangles(core::triangle3df* triangles, s32 arraySize,
		s32& outTriangleCount, const core::line3d<f32>& line,
		const core::matrix4* transform) const
{
#if 0
	core::aabbox3d<f32> box(line.start);
	box.addInternalPoint(line.end);

	// TODO: Could be optimized for line a little bit more.
	COctreeTriangleSelector::getTriangles(triangles, arraySize, outTriangleCount,
		box, transform);
#else

	core::matrix4 mat ( core::matrix4::EM4CONST_NOTHING );

	core::vector3df vectStartInv ( line.start ), vectEndInv ( line.end );
	if (SceneNode)
	{
		mat = SceneNode->getAbsoluteTransformation();
		mat.makeInverse();
		mat.transformVect(vectStartInv, line.start);
		mat.transformVect(vectEndInv, line.end);
	}
	core::line3d<f32> invline(vectStartInv, vectEndInv);

	mat.makeIdentity();

	if (transform)
		mat = (*transform);

	if (SceneNode)
		mat *= SceneNode->getAbsoluteTransformation();

	s32 trianglesWritten = 0;

	if (Root)
		getTrianglesFromOctree(Root, trianglesWritten, arraySize, invline, &mat, triangles);

	outTriangleCount = trianglesWritten;
#endif
}
	void COctreeTriangleSelector::getTrianglesFromOctree(SOctreeNode* node,
		SINT32& trianglesWritten, SINT32 maximumSize, const line3d<FLOAT32>& line,
		const Matrix4* transform, triangle3df* triangles) const
	{
		if (!node->Box.intersectsWithLine(line))
			return;

		SINT32 cnt = node->Triangles.size();
		if (cnt + trianglesWritten > maximumSize)
			cnt -= cnt + trianglesWritten - maximumSize;

		SINT32 i;

		if (transform->isIdentify())
		{
			for (i = 0; i<cnt; ++i)
			{
				triangles[trianglesWritten] = node->Triangles[i];
				++trianglesWritten;
			}
		}
		else
		{
			for (i = 0; i<cnt; ++i)
			{
				triangles[trianglesWritten] = node->Triangles[i];
				//transform->transformVect(triangles[trianglesWritten].pointA);
				//transform->transformVect(triangles[trianglesWritten].pointB);
				//transform->transformVect(triangles[trianglesWritten].pointC);
				triangles[trianglesWritten].pointA = transform->transformAffine(triangles[trianglesWritten].pointA);
				triangles[trianglesWritten].pointB = transform->transformAffine(triangles[trianglesWritten].pointB);
				triangles[trianglesWritten].pointC = transform->transformAffine(triangles[trianglesWritten].pointC);
				++trianglesWritten;
			}
		}

		for (i = 0; i<8; ++i)
			if (node->Child[i])
				getTrianglesFromOctree(node->Child[i], trianglesWritten,
				maximumSize, line, transform, triangles);
	}