Commit 5180ee88 authored by hybrid's avatar hybrid

Enhanced documentation for isFrontFacing to make it safer to use. Fixed...

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: svn://svn.code.sf.net/p/irrlicht/code/trunk@667 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 13f388c6
...@@ -53,7 +53,7 @@ namespace scene ...@@ -53,7 +53,7 @@ namespace scene
{ {
for (s32 i = (s32) MeshBuffers.size(); --i >= 0; ) for (s32 i = (s32) MeshBuffers.size(); --i >= 0; )
{ {
if ( !(material != MeshBuffers[i]->getMaterial()) ) if ( material == MeshBuffers[i]->getMaterial())
return MeshBuffers[i]; return MeshBuffers[i];
} }
......
...@@ -165,8 +165,8 @@ class aabbox3d ...@@ -165,8 +165,8 @@ class aabbox3d
//! Classifies a relation with a plane. //! Classifies a relation with a plane.
//! \param plane: Plane to classify relation to. //! \param plane: Plane to classify relation to.
//! \return Returns ISREL3D_FRONT if the box is in front of the plane, //! \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_BACK if the box is behind the plane, and
//! ISREL3D_CLIPPED if is on both sides of the plane. //! ISREL3D_CLIPPED if it is on both sides of the plane.
EIntersectionRelation3D classifyPlaneRelation(const plane3d<T>& plane) const EIntersectionRelation3D classifyPlaneRelation(const plane3d<T>& plane) const
{ {
vector3d<T> nearPoint(MaxEdge); vector3d<T> nearPoint(MaxEdge);
......
...@@ -181,11 +181,15 @@ class plane3d ...@@ -181,11 +181,15 @@ class plane3d
return false; return false;
} }
//! Returns if the plane is front of backfacing. Note that this only //! Test if the triangle would be front or backfacing from any
//! works if the normal is Normalized. //! 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. //! \param lookDirection: Look direction.
//! \return Returns true if the plane is front facing, which mean it would //! \return Returns true if the plane is front facing and
//! be visible, and false if it is backfacing. //! false if it is backfacing.
bool isFrontFacing(const vector3d<T>& lookDirection) const bool isFrontFacing(const vector3d<T>& lookDirection) const
{ {
const f32 d = Normal.dotProduct(lookDirection); const f32 d = Normal.dotProduct(lookDirection);
......
...@@ -168,15 +168,19 @@ namespace core ...@@ -168,15 +168,19 @@ namespace core
return (pointB - pointA).crossProduct(pointC - pointA); 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. //! \param lookDirection: Look direction.
//! \return Returns true if the plane is front facing, which mean it would //! \return Returns true if the plane is front facing and
//! be visible, and false if it is backfacing. //! false if it is backfacing.
bool isFrontFacing(const vector3d<T>& lookDirection) const bool isFrontFacing(const vector3d<T>& lookDirection) const
{ {
vector3d<T> n = getNormal(); vector3d<T> n = getNormal();
n.normalize(); n.normalize();
return n.dotProduct(lookDirection) <= 0.0f; return F32_LOWER_EQUAL_0(n.dotProduct(lookDirection));
} }
//! Returns the plane of this triangle. //! Returns the plane of this triangle.
......
...@@ -473,7 +473,7 @@ namespace video ...@@ -473,7 +473,7 @@ namespace video
virtual const core::dimension2d<s32>& getOriginalSize() { return size; } virtual const core::dimension2d<s32>& getOriginalSize() { return size; }
virtual const core::dimension2d<s32>& getSize() { return size; } virtual const core::dimension2d<s32>& getSize() { return size; }
virtual E_DRIVER_TYPE getDriverType() { return video::EDT_NULL; } 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 u32 getPitch() const { return 0; }
virtual void regenerateMipMapLevels() {}; virtual void regenerateMipMapLevels() {};
core::dimension2d<s32> size; core::dimension2d<s32> size;
......
...@@ -260,7 +260,7 @@ void CQ3LevelMesh::loadFaces(tBSPLump* l, io::IReadFile* file) ...@@ -260,7 +260,7 @@ void CQ3LevelMesh::loadFaces(tBSPLump* l, io::IReadFile* file)
file->read(Faces, l->length); file->read(Faces, l->length);
#ifdef __BIG_ENDIAN__ #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].textureID = os::Byteswap::byteswap(Faces[i].textureID);
Faces[i].effect = os::Byteswap::byteswap(Faces[i].effect); Faces[i].effect = os::Byteswap::byteswap(Faces[i].effect);
......
...@@ -13,13 +13,12 @@ namespace scene ...@@ -13,13 +13,12 @@ namespace scene
{ {
CQuake3ShaderSceneNode::CQuake3ShaderSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr,s32 id, CQuake3ShaderSceneNode::CQuake3ShaderSceneNode(
io::IFileSystem *fileSystem, scene::ISceneNode* parent, scene::ISceneManager* mgr,s32 id,
scene::IMeshBuffer *buffer, const quake3::SShader * shader io::IFileSystem *fileSystem, scene::IMeshBuffer *buffer,
) const quake3::SShader * shader)
: scene::ISceneNode(parent, mgr, id), Shader ( shader ),TimeAbs ( 0.f ) : scene::ISceneNode(parent, mgr, id), Shader ( shader ),TimeAbs ( 0.f )
{ {
#ifdef _DEBUG #ifdef _DEBUG
core::stringc dName = "CQuake3ShaderSceneNode "; core::stringc dName = "CQuake3ShaderSceneNode ";
dName += Shader->name; dName += Shader->name;
...@@ -499,7 +498,6 @@ u32 CQuake3ShaderSceneNode::animate( u32 stage,core::matrix4 &texture ) ...@@ -499,7 +498,6 @@ u32 CQuake3ShaderSceneNode::animate( u32 stage,core::matrix4 &texture )
const quake3::SVarGroup *group = Shader->getGroup ( stage ); const quake3::SVarGroup *group = Shader->getGroup ( stage );
// select current texture // select current texture
if ( Q3Texture [ stage ].TextureFrequency != 0.f ) if ( Q3Texture [ stage ].TextureFrequency != 0.f )
{ {
...@@ -512,7 +510,6 @@ u32 CQuake3ShaderSceneNode::animate( u32 stage,core::matrix4 &texture ) ...@@ -512,7 +510,6 @@ u32 CQuake3ShaderSceneNode::animate( u32 stage,core::matrix4 &texture )
core::matrix4 m2; core::matrix4 m2;
quake3::SModifierFunction function; quake3::SModifierFunction function;
f32 f0; f32 f0;
f32 f1; f32 f1;
u32 textureMatrixFound = 0; u32 textureMatrixFound = 0;
......
...@@ -805,7 +805,7 @@ bool CSceneManager::isCulled(ISceneNode* node) ...@@ -805,7 +805,7 @@ bool CSceneManager::isCulled(ISceneNode* node)
{ {
ICameraSceneNode* cam = getActiveCamera(); ICameraSceneNode* cam = getActiveCamera();
if (!cam) if (!cam)
return false; return true;
switch ( node->getAutomaticCulling() ) switch ( node->getAutomaticCulling() )
{ {
...@@ -820,14 +820,13 @@ bool CSceneManager::isCulled(ISceneNode* node) ...@@ -820,14 +820,13 @@ bool CSceneManager::isCulled(ISceneNode* node)
// can be seen by a bounding sphere // can be seen by a bounding sphere
case scene::EAC_FRUSTUM_SPHERE: case scene::EAC_FRUSTUM_SPHERE:
{ { // requires bbox diameter
}; };
break; break;
// can be seen by cam pyramid planes ? // can be seen by cam pyramid planes ?
case scene::EAC_FRUSTUM_BOX: case scene::EAC_FRUSTUM_BOX:
{ {
SViewFrustum frust = *cam->getViewFrustum(); SViewFrustum frust = *cam->getViewFrustum();
//transform the frustum to the node's current absolute transformation //transform the frustum to the node's current absolute transformation
...@@ -838,29 +837,24 @@ bool CSceneManager::isCulled(ISceneNode* node) ...@@ -838,29 +837,24 @@ bool CSceneManager::isCulled(ISceneNode* node)
core::vector3df edges[8]; core::vector3df edges[8];
node->getBoundingBox().getEdges(edges); node->getBoundingBox().getEdges(edges);
bool visible = true;
for (s32 i=0; i<scene::SViewFrustum::VF_PLANE_COUNT; ++i) for (s32 i=0; i<scene::SViewFrustum::VF_PLANE_COUNT; ++i)
{ {
bool boxInFrustum = false; u32 inFrustum=0, outFrustum=0;
for (u32 j=0; (j<8) && (inFrustum==0 || outFrustum==0); ++j)
for (u32 j=0; j<8; ++j)
{
if (frust.planes[i].isFrontFacing(edges[j]) )
{
boxInFrustum = true;
break;
}
}
if (!boxInFrustum)
{ {
visible = false; if (frust.planes[i].classifyPointRelation(edges[j]) != core::ISREL3D_FRONT)
break; ++inFrustum;
else
++outFrustum;
} }
if (inFrustum==0)
return true;
else if (outFrustum)
return false;
} }
return !visible; return false;
} }
break; break;
case scene::EAC_OFF: case scene::EAC_OFF:
......
...@@ -72,12 +72,6 @@ const core::aabbox3d<f32>& CTextSceneNode::getBoundingBox() const ...@@ -72,12 +72,6 @@ const core::aabbox3d<f32>& CTextSceneNode::getBoundingBox() const
return Box; return Box;
} }
//! returns amount of materials used by this scene node.
u32 CTextSceneNode::getMaterialCount()
{
return 0;
}
//! sets the text string //! sets the text string
void CTextSceneNode::setText(const wchar_t* text) void CTextSceneNode::setText(const wchar_t* text)
{ {
......
...@@ -38,9 +38,6 @@ namespace scene ...@@ -38,9 +38,6 @@ namespace scene
//! returns the axis aligned bounding box of this node //! returns the axis aligned bounding box of this node
virtual const core::aabbox3d<f32>& getBoundingBox() const; virtual const core::aabbox3d<f32>& getBoundingBox() const;
//! returns amount of materials used by this scene node.
virtual u32 getMaterialCount();
//! sets the text string //! sets the text string
virtual void setText(const wchar_t* text); virtual void setText(const wchar_t* text);
......
...@@ -305,21 +305,20 @@ private: ...@@ -305,21 +305,20 @@ private:
core::vector3df edges[8]; core::vector3df edges[8];
Box.getEdges(edges); Box.getEdges(edges);
u32 bitTest = 0;
for (i=0; i<scene::SViewFrustum::VF_PLANE_COUNT; ++i) 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) for (int j=0; j<8; ++j)
// if (frustum.planes[i].classifyPointRelation(edges[j]) != core::ISREL3D_BACK) if (frustum.planes[i].classifyPointRelation(edges[j]) != core::ISREL3D_FRONT)
if (!frustum.planes[i].isFrontFacing(edges[j]) ) ++inFrustum;
{ else
boxInFrustum = true; ++outFrustum;
break;
}
if (!boxInFrustum) if (!inFrustum) // all edges outside
return; return;
else if (outFrustum) // intersection of plane
break;
} }
} }
......
...@@ -38,7 +38,6 @@ namespace irr ...@@ -38,7 +38,6 @@ namespace irr
#define COLOR_BRIGHT_WHITE 0xFFFFFFFF #define COLOR_BRIGHT_WHITE 0xFFFFFFFF
#define VIDEO_SAMPLE_GRANULARITY 2 #define VIDEO_SAMPLE_GRANULARITY 2
#define ECF_SOFTWARE2 ECF_A8R8G8B8
#else #else
typedef u16 tVideoSample; typedef u16 tVideoSample;
...@@ -56,7 +55,6 @@ namespace irr ...@@ -56,7 +55,6 @@ namespace irr
#define COLOR_MAX 0x1F #define COLOR_MAX 0x1F
#define COLOR_BRIGHT_WHITE 0xFFFF #define COLOR_BRIGHT_WHITE 0xFFFF
#define VIDEO_SAMPLE_GRANULARITY 1 #define VIDEO_SAMPLE_GRANULARITY 1
#define ECF_SOFTWARE2 ECF_A1R5G5B5
#endif #endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment