Enhanced documentation for isFrontFacing to make it safer to use. Fixed frustum culling to correctly handle all possible cases of box intersections. Replaced isFrontFacing by classifyPointRelation as suggested by vitek. Minor cleanups in some classes.

git-svn-id: http://svn.code.sf.net/p/irrlicht/code/trunk@667 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
hybrid 2007-05-28 11:14:47 +00:00
parent aa35f63924
commit c4aec3a721
12 changed files with 47 additions and 60 deletions

View File

@ -53,7 +53,7 @@ namespace scene
{
for (s32 i = (s32) MeshBuffers.size(); --i >= 0; )
{
if ( !(material != MeshBuffers[i]->getMaterial()) )
if ( material == MeshBuffers[i]->getMaterial())
return MeshBuffers[i];
}

View File

@ -165,8 +165,8 @@ class aabbox3d
//! Classifies a relation with a plane.
//! \param plane: Plane to classify relation to.
//! \return Returns ISREL3D_FRONT if the box is in front of the plane,
//! ISREL3D_BACK if the box is back of the plane, and
//! ISREL3D_CLIPPED if is on both sides of the plane.
//! ISREL3D_BACK if the box is behind the plane, and
//! ISREL3D_CLIPPED if it is on both sides of the plane.
EIntersectionRelation3D classifyPlaneRelation(const plane3d<T>& plane) const
{
vector3d<T> nearPoint(MaxEdge);

View File

@ -181,11 +181,15 @@ class plane3d
return false;
}
//! Returns if the plane is front of backfacing. Note that this only
//! works if the normal is Normalized.
//! Test if the triangle would be front or backfacing from any
//! point. Thus, this method assumes a camera position from
//! which the triangle is definitely visible when looking into
//! the given direction.
//! Note that this only works if the normal is Normalized.
//! Do not use this method with points as it will give wrong results!
//! \param lookDirection: Look direction.
//! \return Returns true if the plane is front facing, which mean it would
//! be visible, and false if it is backfacing.
//! \return Returns true if the plane is front facing and
//! false if it is backfacing.
bool isFrontFacing(const vector3d<T>& lookDirection) const
{
const f32 d = Normal.dotProduct(lookDirection);

View File

@ -168,15 +168,19 @@ namespace core
return (pointB - pointA).crossProduct(pointC - pointA);
}
//! Returns if the triangle is front of backfacing.
//! Test if the triangle would be front or backfacing from any
//! point. Thus, this method assumes a camera position from
//! which the triangle is definitely visible when looking into
//! the given direction.
//! Do not use this method with points as it will give wrong results!
//! \param lookDirection: Look direction.
//! \return Returns true if the plane is front facing, which mean it would
//! be visible, and false if it is backfacing.
//! \return Returns true if the plane is front facing and
//! false if it is backfacing.
bool isFrontFacing(const vector3d<T>& lookDirection) const
{
vector3d<T> n = getNormal();
n.normalize();
return n.dotProduct(lookDirection) <= 0.0f;
return F32_LOWER_EQUAL_0(n.dotProduct(lookDirection));
}
//! Returns the plane of this triangle.

View File

@ -473,7 +473,7 @@ namespace video
virtual const core::dimension2d<s32>& getOriginalSize() { return size; }
virtual const core::dimension2d<s32>& getSize() { return size; }
virtual E_DRIVER_TYPE getDriverType() { return video::EDT_NULL; }
virtual ECOLOR_FORMAT getColorFormat() const { return video::ECF_R5G6B5; };
virtual ECOLOR_FORMAT getColorFormat() const { return video::ECF_A1R5G5B5; };
virtual u32 getPitch() const { return 0; }
virtual void regenerateMipMapLevels() {};
core::dimension2d<s32> size;

View File

@ -260,7 +260,7 @@ void CQ3LevelMesh::loadFaces(tBSPLump* l, io::IReadFile* file)
file->read(Faces, l->length);
#ifdef __BIG_ENDIAN__
for ( u32 i=0;i<NumFaces;i++)
for ( s32 i=0;i<NumFaces;i++)
{
Faces[i].textureID = os::Byteswap::byteswap(Faces[i].textureID);
Faces[i].effect = os::Byteswap::byteswap(Faces[i].effect);

View File

@ -13,13 +13,12 @@ namespace scene
{
CQuake3ShaderSceneNode::CQuake3ShaderSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr,s32 id,
io::IFileSystem *fileSystem,
scene::IMeshBuffer *buffer, const quake3::SShader * shader
)
: scene::ISceneNode(parent, mgr, id), Shader ( shader ),TimeAbs ( 0.f )
CQuake3ShaderSceneNode::CQuake3ShaderSceneNode(
scene::ISceneNode* parent, scene::ISceneManager* mgr,s32 id,
io::IFileSystem *fileSystem, scene::IMeshBuffer *buffer,
const quake3::SShader * shader)
: scene::ISceneNode(parent, mgr, id), Shader ( shader ),TimeAbs ( 0.f )
{
#ifdef _DEBUG
core::stringc dName = "CQuake3ShaderSceneNode ";
dName += Shader->name;
@ -499,7 +498,6 @@ u32 CQuake3ShaderSceneNode::animate( u32 stage,core::matrix4 &texture )
const quake3::SVarGroup *group = Shader->getGroup ( stage );
// select current texture
if ( Q3Texture [ stage ].TextureFrequency != 0.f )
{
@ -512,7 +510,6 @@ u32 CQuake3ShaderSceneNode::animate( u32 stage,core::matrix4 &texture )
core::matrix4 m2;
quake3::SModifierFunction function;
f32 f0;
f32 f1;
u32 textureMatrixFound = 0;

View File

@ -805,7 +805,7 @@ bool CSceneManager::isCulled(ISceneNode* node)
{
ICameraSceneNode* cam = getActiveCamera();
if (!cam)
return false;
return true;
switch ( node->getAutomaticCulling() )
{
@ -820,14 +820,13 @@ bool CSceneManager::isCulled(ISceneNode* node)
// can be seen by a bounding sphere
case scene::EAC_FRUSTUM_SPHERE:
{
{ // requires bbox diameter
};
break;
// can be seen by cam pyramid planes ?
case scene::EAC_FRUSTUM_BOX:
{
SViewFrustum frust = *cam->getViewFrustum();
//transform the frustum to the node's current absolute transformation
@ -838,29 +837,24 @@ bool CSceneManager::isCulled(ISceneNode* node)
core::vector3df edges[8];
node->getBoundingBox().getEdges(edges);
bool visible = true;
for (s32 i=0; i<scene::SViewFrustum::VF_PLANE_COUNT; ++i)
{
bool boxInFrustum = false;
for (u32 j=0; j<8; ++j)
u32 inFrustum=0, outFrustum=0;
for (u32 j=0; (j<8) && (inFrustum==0 || outFrustum==0); ++j)
{
if (frust.planes[i].isFrontFacing(edges[j]) )
{
boxInFrustum = true;
break;
}
}
if (!boxInFrustum)
{
visible = false;
break;
if (frust.planes[i].classifyPointRelation(edges[j]) != core::ISREL3D_FRONT)
++inFrustum;
else
++outFrustum;
}
if (inFrustum==0)
return true;
else if (outFrustum)
return false;
}
return !visible;
return false;
}
break;
case scene::EAC_OFF:

View File

@ -72,12 +72,6 @@ const core::aabbox3d<f32>& CTextSceneNode::getBoundingBox() const
return Box;
}
//! returns amount of materials used by this scene node.
u32 CTextSceneNode::getMaterialCount()
{
return 0;
}
//! sets the text string
void CTextSceneNode::setText(const wchar_t* text)
{

View File

@ -38,9 +38,6 @@ namespace scene
//! returns the axis aligned bounding box of this node
virtual const core::aabbox3d<f32>& getBoundingBox() const;
//! returns amount of materials used by this scene node.
virtual u32 getMaterialCount();
//! sets the text string
virtual void setText(const wchar_t* text);

View File

@ -305,21 +305,20 @@ private:
core::vector3df edges[8];
Box.getEdges(edges);
u32 bitTest = 0;
for (i=0; i<scene::SViewFrustum::VF_PLANE_COUNT; ++i)
{
bool boxInFrustum = false;
u32 inFrustum=0, outFrustum=0;
for (int j=0; j<8; ++j)
// if (frustum.planes[i].classifyPointRelation(edges[j]) != core::ISREL3D_BACK)
if (!frustum.planes[i].isFrontFacing(edges[j]) )
{
boxInFrustum = true;
break;
}
if (frustum.planes[i].classifyPointRelation(edges[j]) != core::ISREL3D_FRONT)
++inFrustum;
else
++outFrustum;
if (!boxInFrustum)
if (!inFrustum) // all edges outside
return;
else if (outFrustum) // intersection of plane
break;
}
}

View File

@ -38,7 +38,6 @@ namespace irr
#define COLOR_BRIGHT_WHITE 0xFFFFFFFF
#define VIDEO_SAMPLE_GRANULARITY 2
#define ECF_SOFTWARE2 ECF_A8R8G8B8
#else
typedef u16 tVideoSample;
@ -56,7 +55,6 @@ namespace irr
#define COLOR_MAX 0x1F
#define COLOR_BRIGHT_WHITE 0xFFFF
#define VIDEO_SAMPLE_GRANULARITY 1
#define ECF_SOFTWARE2 ECF_A1R5G5B5
#endif