Some documentation fixes.

Replaced some f64 by T in container classes, where computations were only f32 correct anyway.
Made triangle3d.isOnSameSide private as it is completely unrelated to triangles.
Renamed plane.existsInterSection to plane.existsIntersection since all other functions concerning intersections use the small s.
Fixed plane3d.classifyPointRelation to return the correct relation. Spotted by vitek.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@655 dfc29bdd-3216-0410-991c-e03cc46cb475
master
hybrid 2007-05-27 00:04:58 +00:00
parent 4c2e3119f4
commit 4f5e1c399f
8 changed files with 130 additions and 169 deletions

View File

@ -1,7 +1,12 @@
Changes in version 1.3.1 (?? Mar 2007)
- updated to latest PNG library (1.2.18), fixing a vulnerability and the odd
compile problem due to wrong defines.
- Some fixes in the 3d basic structures: plane3d.classifyPointRelation no
correctly returns the relation, it returned the opposite before. Also
renamed existsInterSection to existsIntersection for consistency.
triangle3d.isOnSameSide is now private - it's just a helper class not
intended for further use.
- updated to latest PNG library (1.2.18), fixing a vulnerability.
- Changed the external window pointer from s32 to void*. This makes the
mechanism 64bit safe, but also breaks the API. You have to cast to

View File

@ -24,7 +24,6 @@ class line3d
line3d() : start(0,0,0), end(1,1,1) {};
line3d(T xa, T ya, T za, T xb, T yb, T zb) : start(xa, ya, za), end(xb, yb, zb) {};
line3d(const vector3d<T>& start, const vector3d<T>& end) : start(start), end(end) {};
line3d(const line3d<T>& other) : start(other.start), end(other.end) {};
// operators
@ -39,13 +38,13 @@ class line3d
// functions
void setLine(const T& xa, const T& ya, const T& za, const T& xb, const T& yb, const T& zb){start.set(xa, ya, za); end.set(xb, yb, zb);}
void setLine(const vector3d<T>& nstart, const vector3d<T>& nend){start.set(nstart); end.set(nend);}
void setLine(const line3d<T>& line){start.set(line.start); end.set(line.end);}
void setLine(const T& xa, const T& ya, const T& za, const T& xb, const T& yb, const T& zb) {start.set(xa, ya, za); end.set(xb, yb, zb);}
void setLine(const vector3d<T>& nstart, const vector3d<T>& nend) {start.set(nstart); end.set(nend);}
void setLine(const line3d<T>& line) {start.set(line.start); end.set(line.end);}
//! Returns length of line
//! \return Returns length of line.
f64 getLength() const { return start.getDistanceFrom(end); };
T getLength() const { return start.getDistanceFrom(end); };
//! Returns sqared length of line
//! \return Returns sqared length of line.
@ -79,8 +78,10 @@ class line3d
v /= d;
T t = v.dotProduct(c);
if (t < (T)0.0) return start;
if (t > d) return end;
if (t < (T)0.0)
return start;
if (t > d)
return end;
v *= t;
return start + v;
@ -88,19 +89,19 @@ class line3d
//! Returns if the line intersects with a shpere
//! \param sorigin: Origin of the shpere.
//! \param sradius: Radius if the sphere.
//! \param sradius: Radius of the sphere.
//! \param outdistance: The distance to the first intersection point.
//! \return Returns true if there is an intersection.
//! If there is one, the distance to the first intersection point
//! is stored in outdistance.
bool getIntersectionWithSphere(vector3d<T> sorigin, T sradius, f64& outdistance) const
{
vector3d<T> q = sorigin - start;
f64 c = q.getLength();
f64 v = q.dotProduct(getVector().normalize());
f64 d = sradius * sradius - (c*c - v*v);
const vector3d<T> q = sorigin - start;
T c = q.getLength();
T v = q.dotProduct(getVector().normalize());
T d = sradius * sradius - (c*c - v*v);
if (d < 0.0)
if (d < 0.0)
return false;
outdistance = v - sqrt(d);
@ -108,12 +109,12 @@ class line3d
}
// member variables
vector3d<T> start;
vector3d<T> end;
};
//! Typedef for a f32 line.
//! Typedef for an f32 line.
typedef line3d<f32> line3df;
//! Typedef for an integer line.
typedef line3d<s32> line3di;

View File

@ -14,7 +14,7 @@ namespace core
{
//! Enumeration for intersection relations of 3d objects
enum EIntersectionRelation3D
enum EIntersectionRelation3D
{
ISREL3D_FRONT = 0,
ISREL3D_BACK,
@ -34,7 +34,6 @@ class plane3d
plane3d(): Normal(0,1,0) { recalculateD(vector3d<T>(0,0,0)); };
plane3d(const vector3d<T>& MPoint, const vector3d<T>& Normal) : Normal(Normal) { recalculateD(MPoint); };
plane3d(T px, T py, T pz, T nx, T ny, T nz) : Normal(nx, ny, nz) { recalculateD(vector3d<T>(px, py, pz)); };
plane3d(const plane3d<T>& other) : Normal(other.Normal), D(other.D) {};
plane3d(const vector3d<T>& point1, const vector3d<T>& point2, const vector3d<T>& point3) { setPlane(point1, point2, point3); };
// operators
@ -47,7 +46,6 @@ class plane3d
void setPlane(const vector3d<T>& point, const vector3d<T>& nvector)
{
Normal = nvector;
Normal.normalize();
recalculateD(point);
}
@ -80,7 +78,7 @@ class plane3d
if (t2 == 0)
return false;
T t =- (Normal.dotProduct(linePoint) + D) / t2;
T t =- (Normal.dotProduct(linePoint) + D) / t2;
outIntersection = linePoint + (lineVect * t);
return true;
}
@ -104,7 +102,7 @@ class plane3d
//! \param linePoint2: Point 2 of the line.
//! \param outIntersection: Place to store the intersection point, if there is one.
//! \return Returns true if there was an intersection, false if there was not.
bool getIntersectionWithLimitedLine(const vector3d<T>& linePoint1,
bool getIntersectionWithLimitedLine(const vector3d<T>& linePoint1,
const vector3d<T>& linePoint2, vector3d<T>& outIntersection) const
{
return ( getIntersectionWithLine(linePoint1, linePoint2 - linePoint1, outIntersection) &&
@ -121,10 +119,10 @@ class plane3d
const T d = Normal.dotProduct(point) + D;
if (d < -ROUNDING_ERROR_32)
return ISREL3D_FRONT;
return ISREL3D_BACK;
if (d > ROUNDING_ERROR_32)
return ISREL3D_BACK;
return ISREL3D_FRONT;
return ISREL3D_PLANAR;
}
@ -142,9 +140,9 @@ class plane3d
return Normal * -D;
}
//! Tests if there is a intersection between this plane and another
//! Tests if there is an intersection between with the other plane
//! \return Returns true if there is a intersection.
bool existsInterSection(const plane3d<T>& other) const
bool existsIntersection(const plane3d<T>& other) const
{
vector3d<T> cross = other.Normal.crossProduct(Normal);
return cross.getLength() > core::ROUNDING_ERROR_32;
@ -155,9 +153,9 @@ class plane3d
bool getIntersectionWithPlane(const plane3d<T>& other, vector3d<T>& outLinePoint,
vector3d<T>& outLineVect) const
{
f64 fn00 = Normal.getLength();
f64 fn01 = Normal.dotProduct(other.Normal);
f64 fn11 = other.Normal.getLength();
T fn00 = Normal.getLength();
T fn01 = Normal.dotProduct(other.Normal);
T fn11 = other.Normal.getLength();
f64 det = fn00*fn11 - fn01*fn01;
if (fabs(det) < ROUNDING_ERROR_64 )
@ -173,7 +171,7 @@ class plane3d
}
//! Returns the intersection point with two other planes if there is one.
bool getIntersectionWithPlanes(const plane3d<T>& o1,
bool getIntersectionWithPlanes(const plane3d<T>& o1,
const plane3d<T>& o2, vector3d<T>& outPoint) const
{
vector3d<T> linePoint, lineVect;
@ -200,11 +198,11 @@ class plane3d
{
return point.dotProduct(Normal) + D;
}
// member variables
vector3d<T> Normal; // normal vector
T D; // distance from origin
T D; // distance from origin
};

View File

@ -21,12 +21,26 @@ namespace core
{
public:
//! Constructor for an all 0 triangle
triangle3d() {}
//! Constructor for triangle with given three vertices
triangle3d(vector3d<T> v1, vector3d<T> v2, vector3d<T> v3) : pointA(v1), pointB(v2), pointC(v3) {}
//! Equality operator
bool operator==(const triangle3d<T>& other) const
{
return other.pointA==pointA && other.pointB==pointB && other.pointC==pointC;
}
//! Inequality operator
bool operator!=(const triangle3d<T>& other) const
{
return !(*this==other);
}
//! Determines if the triangle is totally inside a bounding box.
//! \param box: Box to check.
//! \return Returns true if the triangle is withing the box,
//! \return Returns true if the triangle is within the box,
//! and false otherwise.
bool isTotalInsideBox(const aabbox3d<T>& box) const
{
@ -35,20 +49,18 @@ namespace core
box.isPointInside(pointC));
}
bool operator==(const triangle3d<T>& other) const { return other.pointA==pointA && other.pointB==pointB && other.pointC==pointC; }
bool operator!=(const triangle3d<T>& other) const { return other.pointA!=pointA || other.pointB!=pointB || other.pointC!=pointC; }
//! Returns the closest point on a triangle to a point on the same plane.
//! Get the closest point on a triangle to a point on the same plane.
//! \param p: Point which must be on the same plane as the triangle.
//! \return The closest point of the triangle
core::vector3d<T> closestPointOnTriangle(const core::vector3d<T>& p) const
{
core::vector3d<T> rab = line3d<T>(pointA, pointB).getClosestPoint(p);
core::vector3d<T> rbc = line3d<T>(pointB, pointC).getClosestPoint(p);
core::vector3d<T> rca = line3d<T>(pointC, pointA).getClosestPoint(p);
const core::vector3d<T> rab = line3d<T>(pointA, pointB).getClosestPoint(p);
const core::vector3d<T> rbc = line3d<T>(pointB, pointC).getClosestPoint(p);
const core::vector3d<T> rca = line3d<T>(pointC, pointA).getClosestPoint(p);
T d1 = rab.getDistanceFrom(p);
T d2 = rbc.getDistanceFrom(p);
T d3 = rca.getDistanceFrom(p);
const T d1 = rab.getDistanceFrom(p);
const T d2 = rbc.getDistanceFrom(p);
const T d3 = rca.getDistanceFrom(p);
if (d1 < d2)
return d1 < d3 ? rab : rca;
@ -56,7 +68,7 @@ namespace core
return d2 < d3 ? rbc : rca;
}
//! Returns if a point is inside the triangle
//! Check if a point is inside the triangle
//! \param p: Point to test. Assumes that this point is already on the plane
//! of the triangle.
//! \return Returns true if the point is inside the triangle, otherwise false.
@ -67,7 +79,7 @@ namespace core
isOnSameSide(p, pointC, pointA, pointB));
}
//! Returns if a point is inside the triangle. This method is an implementation
//! Check if a point is inside the triangle. This method is an implementation
//! of the example used in a paper by Kasper Fauerby original written
//! by Keidy from Mr-Gamemaker.
//! \param p: Point to test. Assumes that this point is already on the plane
@ -95,20 +107,10 @@ namespace core
}
bool isOnSameSide(const vector3d<T>& p1, const vector3d<T>& p2,
const vector3d<T>& a, const vector3d<T>& b) const
{
vector3d<T> bminusa = b - a;
vector3d<T> cp1 = bminusa.crossProduct(p1 - a);
vector3d<T> cp2 = bminusa.crossProduct(p2 - a);
return (cp1.dotProduct(cp2) >= 0.0f);
}
//! Returns an intersection with a 3d line.
//! Get an intersection with a 3d line.
//! \param line: Line to intersect with.
//! \param outIntersection: Place to store the intersection point, if there is one.
//! \return Returns true if there was an intersection, false if there was not.
//! \return Returns true if there was an intersection, false if not.
bool getIntersectionWithLimitedLine(const line3d<T>& line,
vector3d<T>& outIntersection) const
{
@ -119,12 +121,12 @@ namespace core
//! Returns an intersection with a 3d line.
//! Please note that also points are returned as intersection, which
//! Please note that also points are returned as intersection which
//! are on the line, but not between the start and end point of the line.
//! If you want the returned point be between start and end, please
//! If you want the returned point be between start and end
//! use getIntersectionWithLimitedLine().
//! \param lineVect: Vector of the line to intersect with.
//! \param linePoint: Point of the line to intersect with.
//! \param lineVect: Vector of the line to intersect with.
//! \param outIntersection: Place to store the intersection point, if there is one.
//! \return Returns true if there was an intersection, false if there was not.
bool getIntersectionWithLine(const vector3d<T>& linePoint,
@ -148,7 +150,7 @@ namespace core
{
const vector3d<T> normal = getNormal().normalize();
T t2;
if ( core::iszero ( t2 = normal.dotProduct(lineVect) ) )
return false;
@ -202,6 +204,16 @@ namespace core
vector3d<T> pointA;
vector3d<T> pointB;
vector3d<T> pointC;
private:
bool isOnSameSide(const vector3d<T>& p1, const vector3d<T>& p2,
const vector3d<T>& a, const vector3d<T>& b) const
{
vector3d<T> bminusa = b - a;
vector3d<T> cp1 = bminusa.crossProduct(p1 - a);
vector3d<T> cp2 = bminusa.crossProduct(p2 - a);
return (cp1.dotProduct(cp2) >= 0.0f);
}
};

View File

@ -67,7 +67,7 @@ public:
//! Returns the length of the vector
//! \return Returns the length of the vector.
f64 getLength() const { return sqrt(X*X + Y*Y); }
T getLength() const { return (T)sqrt(X*X + Y*Y); }
//! Returns the squared length of this vector
/** This is useful because it is much faster than getLength(). */
@ -81,7 +81,7 @@ public:
//! Returns distance from another point. Here, the vector is interpreted
//! as a point in 2 dimensional space.
f64 getDistanceFrom(const vector2d<T>& other) const
T getDistanceFrom(const vector2d<T>& other) const
{
return vector2d<T>(X - other.X, Y - other.Y).getLength();
}
@ -130,19 +130,19 @@ public:
//! \return Returns a value between 0 and 360.
f64 getAngleTrig() const
{
if (X == 0.0)
return Y < 0.0 ? 270.0 : 90.0;
if (X == 0)
return Y < 0 ? 270 : 90;
else
if (Y == 0)
return X < 0.0 ? 180.0 : 0.0;
return X < 0 ? 180 : 0;
if ( Y > 0.0)
if (X > 0.0)
if ( Y > 0)
if (X > 0)
return atan(Y/X) * RADTODEG64;
else
return 180.0-atan(Y/-X) * RADTODEG64;
else
if (X > 0.0)
if (X > 0)
return 360.0-atan(-Y/X) * RADTODEG64;
else
return 180.0+atan(-Y/-X) * RADTODEG64;
@ -152,24 +152,24 @@ public:
//! \return Returns a value between 0 and 360.
inline f64 getAngle() const
{
if (Y == 0.0) // corrected thanks to a suggestion by Jox
return X < 0.0 ? 180.0 : 0.0;
else if (X == 0.0)
return Y < 0.0 ? 90.0 : 270.0;
if (Y == 0) // corrected thanks to a suggestion by Jox
return X < 0 ? 180 : 0;
else if (X == 0)
return Y < 0 ? 90 : 270;
f64 tmp = Y / getLength();
tmp = atan(sqrt(1 - tmp*tmp) / tmp) * RADTODEG64;
if (X>0.0 && Y>0.0)
if (X>0 && Y>0)
return tmp + 270;
else
if (X>0.0 && Y<0.0)
if (X>0 && Y<0)
return tmp + 90;
else
if (X<0.0 && Y<0.0)
if (X<0 && Y<0)
return 90 - tmp;
else
if (X<0.0 && Y>0.0)
if (X<0 && Y>0)
return 270 - tmp;
return tmp;
@ -185,7 +185,8 @@ public:
return 90.0;
tmp = tmp / sqrt((X*X + Y*Y) * (b.X*b.X + b.Y*b.Y));
if (tmp < 0.0) tmp = -tmp;
if (tmp < 0.0)
tmp = -tmp;
return atan(sqrt(1 - tmp*tmp) / tmp) * RADTODEG64;
}

View File

@ -11,10 +11,10 @@ namespace irr
{
namespace core
{
//! 3d vector template class with lots of operators and methods.
template <class T>
class vector3d
class vector3d
{
public:
@ -23,7 +23,7 @@ namespace core
#else
vector3d() : X(0), Y(0), Z(0) {};
#endif
vector3d(T nx, T ny, T nz) : X(nx), Y(ny), Z(nz) {};
vector3d(const vector3d<T>& other) : X(other.X), Y(other.Y), Z(other.Z) {};
@ -61,15 +61,15 @@ namespace core
bool operator==(const vector3d<T>& other) const
{
return core::equals(X, other.X) &&
core::equals(Y, other.Y) &&
core::equals(Z, other.Z);
core::equals(Y, other.Y) &&
core::equals(Z, other.Z);
}
bool operator!=(const vector3d<T>& other) const
{
return !core::equals(X, other.X) ||
!core::equals(Y, other.Y) ||
!core::equals(Z, other.Z);
!core::equals(Y, other.Y) ||
!core::equals(Z, other.Z);
}
// functions
@ -78,8 +78,8 @@ namespace core
bool equals(const vector3d<T>& other, const f32 tolerance = ROUNDING_ERROR_32 ) const
{
return core::equals(X, other.X, tolerance) &&
core::equals(Y, other.Y, tolerance) &&
core::equals(Z, other.Z, tolerance);
core::equals(Y, other.Y, tolerance) &&
core::equals(Z, other.Z, tolerance);
}
void set(const T nx, const T ny, const T nz) {X=nx; Y=ny; Z=nz; }
@ -101,12 +101,12 @@ namespace core
//! Returns distance from another point.
/** Here, the vector is interpreted as point in 3 dimensional space. */
f64 getDistanceFrom(const vector3d<T>& other) const
T getDistanceFrom(const vector3d<T>& other) const
{
return vector3d<T>(X - other.X, Y - other.Y, Z - other.Z).getLength();
}
//! Returns squared distance from another point.
//! Returns squared distance from another point.
/** Here, the vector is interpreted as point in 3 dimensional space. */
T getDistanceFromSQ(const vector3d<T>& other) const
{
@ -114,8 +114,8 @@ namespace core
}
//! Calculates the cross product with another vector
//! \param p: vector to multiply with.
//! \return Crossproduct of this vector with p.
//! \param p: vector to multiply with.
//! \return Crossproduct of this vector with p.
vector3d<T> crossProduct(const vector3d<T>& p) const
{
return vector3d<T>(Y * p.Z - Z * p.Y, Z * p.X - X * p.Z, X * p.Y - Y * p.X);
@ -123,13 +123,13 @@ namespace core
//! Returns if this vector interpreted as a point is on a line between two other points.
/** It is assumed that the point is on the line. */
//! \param begin: Beginning vector to compare between.
//! \param end: Ending vector to compare between.
//! \return True if this vector is between begin and end. False if not.
//! \param begin: Beginning vector to compare between.
//! \param end: Ending vector to compare between.
//! \return True if this vector is between begin and end. False if not.
bool isBetweenPoints(const vector3d<T>& begin, const vector3d<T>& end) const
{
T f = (end - begin).getLengthSQ();
return getDistanceFromSQ(begin) < f &&
return getDistanceFromSQ(begin) < f &&
getDistanceFromSQ(end) < f;
}
@ -163,7 +163,7 @@ namespace core
Z *= -1.0f;
}
//! Rotates the vector by a specified number of degrees around the Y
//! Rotates the vector by a specified number of degrees around the Y
//! axis and the specified center.
//! \param degrees: Number of degrees to rotate around the Y axis.
//! \param center: The center of the rotation.
@ -179,7 +179,7 @@ namespace core
Z += center.Z;
}
//! Rotates the vector by a specified number of degrees around the Z
//! Rotates the vector by a specified number of degrees around the Z
//! axis and the specified center.
//! \param degrees: Number of degrees to rotate around the Z axis.
//! \param center: The center of the rotation.
@ -239,33 +239,33 @@ namespace core
//! Gets the Y and Z rotations of a vector.
/** Thanks to Arras on the Irrlicht forums to add this method.
\return A vector representing the rotation in degrees of
\return A vector representing the rotation in degrees of
this vector. The Z component of the vector will always be 0. */
vector3d<T> getHorizontalAngle()
{
vector3d<T> angle;
angle.Y = (T)atan2(X, Z);
angle.Y = (T)atan2(X, Z);
angle.Y *= (f32)RADTODEG64;
if (angle.Y < 0.0f) angle.Y += 360.0f;
if (angle.Y >= 360.0f) angle.Y -= 360.0f;
f32 z1 = (f32)sqrt(X*X + Z*Z);
angle.X = (T)atan2(z1, Y);
f32 z1 = (f32)sqrt(X*X + Z*Z);
angle.X = (T)atan2(z1, Y);
angle.X *= (f32)RADTODEG64;
angle.X -= 90.0f;
if (angle.X < 0.0f) angle.X += 360.0f;
if (angle.X >= 360.0f) angle.X -= 360.0f;
angle.X -= 90.0f;
if (angle.X < 0.0f) angle.X += 360.0f;
if (angle.X >= 360.0f) angle.X -= 360.0f;
return angle;
}
//! Fills an array of 4 values with the vector data (usually floats).
/** Useful for setting in shader constants for example. The fourth value
will always be 0. */
will always be 0. */
void getAs4Values(T* array) const
{
array[0] = X;

View File

@ -498,10 +498,10 @@ void CSoftwareDriver::drawClippedIndexedTriangleListT(const VERTEXTYPE* vertices
for (t=0; t<3; ++t)
{
inout[t] = planes[p].classifyPointRelation(tClpBuf[v+t].Pos);
if (inout[t] == core::ISREL3D_FRONT)
if (inout[t] != core::ISREL3D_FRONT)
++inside;
else
if (inout[t] == core::ISREL3D_BACK)
if (inout[t] == core::ISREL3D_FRONT)
++outside;
}

View File

@ -292,70 +292,16 @@ private:
}
#if 0
// returns all ids of polygons partially or full enclosed
// by the view frustum.
void getPolys(const scene::SViewFrustum& frustum, SIndexData* idxdata,u32 parentTest) const
{
// not full inside
//if ( parentTest != 2 )
{
s32 i; // new ISO for scoping problem in some compilers
core::vector3df edges[8];
Box.getEdges(edges);
u32 bitTest = 0;
for (i=0; i<scene::SViewFrustum::VF_PLANE_COUNT; ++i)
{
bool boxInFrustum = false;
for (int j=0; j<8; ++j)
if (frustum.planes[i].classifyPointRelation(edges[j]) != core::ISREL3D_BACK)
{
boxInFrustum = true;
break;
}
if (!boxInFrustum)
{
return;
}
}
}
s32 cnt = IndexData->size();
for (i=0; i<cnt; ++i)
{
s32 idxcnt = (*IndexData)[i].Indices.size();
if (idxcnt)
{
memcpy(&idxdata[i].Indices[idxdata[i].CurrentSize],
&(*IndexData)[i].Indices[0], idxcnt * sizeof(s16));
idxdata[i].CurrentSize += idxcnt;
}
}
for (i=0; i<8; ++i)
if (Children[i])
Children[i]->getPolys(frustum, idxdata,parentTest);
}
#endif
// returns all ids of polygons partially or full enclosed
// by the view frustum.
void getPolys(const scene::SViewFrustum& frustum, SIndexData* idxdata,u32 parentTest) const
{
u32 totalIn = 0;
s32 i; // new ISO for scoping problem in some compilers
// not full inside
// not fully inside
//if ( parentTest != 2 )
{
core::vector3df edges[8];
Box.getEdges(edges);
@ -365,18 +311,16 @@ private:
bool boxInFrustum = false;
for (int j=0; j<8; ++j)
if (frustum.planes[i].isFrontFacing(edges[j]) )
// if (frustum.planes[i].classifyPointRelation(edges[j]) != core::ISREL3D_BACK)
if (!frustum.planes[i].isFrontFacing(edges[j]) )
{
boxInFrustum = true;
break;
}
if (!boxInFrustum)
{
return;
}
}
}
s32 cnt = IndexData->size();