Commit 2dc5c7d7 authored by cutealien's avatar cutealien

- Reversed change in vector3d::normalize. The check for 0 vector isn't there...

- Reversed change in vector3d::normalize. The check for 0 vector isn't there for optimization, but to prevent NAN values.
  Works now again as documented and a corresponding test has been added.
  Does fix bug 2770709 (https://sourceforge.net/tracker/?func=detail&aid=2770709&group_id=74339&atid=540676)
- Animations can now be paused by setting the fps to 0.
- Avoid fp-precision problem in getPickedNodeBB (see also 
http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=33838&highlight=). 
  This change might also fix the problem with picking nodes found by aanderse 
(http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=32890&highlight=)



git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@2419 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 2391338b
......@@ -140,7 +140,10 @@ namespace core
\return Reference to this vector after normalization. */
vector3d<T>& normalize()
{
const f64 length = core::reciprocal_squareroot ( (f64) (X*X + Y*Y + Z*Z) );
f64 length = (f32)(X*X + Y*Y + Z*Z);
if (core::equals(length, 0.0)) // this check isn't an optimization but prevents getting NAN in the sqrt.
return *this;
length = core::reciprocal_squareroot ( (f64) (X*X + Y*Y + Z*Z) );
X = (T)(X * length);
Y = (T)(Y * length);
......
......@@ -107,7 +107,7 @@ void CAnimatedMeshSceneNode::buildFrameNr(u32 timeMs)
}
}
if ((StartFrame==EndFrame) || (FramesPerSecond==0.f))
if ((StartFrame==EndFrame))
{
CurrentFrameNr = (f32)StartFrame; //Support for non animated meshes
}
......
......@@ -149,9 +149,10 @@ void CSceneCollisionManager::getPickedNodeBB(ISceneNode* root, core::line3df& ra
core::vector3df intersection;
core::plane3df facePlane;
f32 bestDistToBoxBorder = FLT_MAX;
f32 bestToIntersectionSq = FLT_MAX;
bool gotHit = false;
for(s32 face = 0; face < 6 && !gotHit; ++face)
for(s32 face = 0; face < 6; ++face)
{
facePlane.setPlane(edges[faceEdges[face][0]],
edges[faceEdges[face][1]],
......@@ -170,20 +171,17 @@ void CSceneCollisionManager::getPickedNodeBB(ISceneNode* root, core::line3df& ra
if(toIntersectionSq < outbestdistance)
{
// We have to check that the intersection with this plane is actually
// on the box, so need to go back to object space again. We also
// need to move the intersection very slightly closer to the centre of
// the box to take into account fp precision losses, since the intersection
// will axiomatically be on the very edge of the box.
// on the box, so need to go back to object space again.
worldToObject.transformVect(intersection);
intersection *= 0.99f;
if(objectBox.isPointInside(intersection))
// find the closes point on the box borders. Have to do this as exact checks will fail due to floating point problems.
f32 distToBorder = core::max_ ( core::min_ (core::abs_(objectBox.MinEdge.X-intersection.X), core::abs_(objectBox.MaxEdge.X-intersection.X)),
core::min_ (core::abs_(objectBox.MinEdge.Y-intersection.Y), core::abs_(objectBox.MaxEdge.Y-intersection.Y)),
core::min_ (core::abs_(objectBox.MinEdge.Z-intersection.Z), core::abs_(objectBox.MaxEdge.Z-intersection.Z)) );
if ( distToBorder < bestDistToBoxBorder )
{
outbestdistance = toIntersectionSq;
outbestnode = current;
// We can only hit one face, so stop checking now.
gotHit = true;
bestDistToBoxBorder = distToBorder;
bestToIntersectionSq = toIntersectionSq;
}
}
}
......@@ -194,11 +192,16 @@ void CSceneCollisionManager::getPickedNodeBB(ISceneNode* root, core::line3df& ra
++face;
}
if ( bestDistToBoxBorder < FLT_MAX )
{
outbestdistance = bestToIntersectionSq;
outbestnode = current;
// If we got a hit, we can now truncate the ray to stop us hitting further nodes.
if (gotHit)
ray.end = ray.start + (rayVector * sqrtf(outbestdistance));
}
}
}
// Only check the children if this node is visible.
getPickedNodeBB(current, ray, bits, bNoDebugObjects, outbestdistance, outbestnode);
......
......@@ -8,13 +8,22 @@
using namespace irr;
using namespace core;
// check if the vector contains a NAN (a==b is guaranteed to return false in this case)
template<class T>
static bool is_nan(const core::vector3d<T> &vec )
{
return ( !(vec.X == vec.X)
|| !(vec.Y == vec.Y)
|| !(vec.Z == vec.Z) );
}
template<class T>
static bool compareVectors(const core::vector3d<T> & compare,
const core::vector3d<T> & with)
{
if(compare != with)
{
logTestString("\nERROR: vector3d %.16f, %.16f, %.16f != vector3d %.16f, %.16f, %.16f\n",
logTestString("\nERROR: vector3dOr %.16f, %.16f, %.16f != vector3d %.16f, %.16f, %.16f\n",
(f64)compare.X, (f64)compare.Y, (f64)compare.Z,
(f64)with.X, (f64)with.Y, (f64)with.Z);
assert(compare == with);
......@@ -114,6 +123,11 @@ static bool doTests()
interpolated = vec.getInterpolated_quadratic(otherVec, thirdVec, 1.f);
COMPARE_VECTORS(interpolated, thirdVec); // 1.f means all the 3rd vector
vec.set(0,0,0);
vec.setLength(99);
if ( is_nan(vec) )
return false;
return true;
}
......
Test suite pass at GMT Wed Jun 10 20:04:22 2009
Test suite pass at GMT Thu Jun 11 22:44:22 2009
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