002
29.11.2003, 12:28 Uhr
bürgi
|
OK (bin immer noch der gleiche bürgi) tschuldigung für die Doppelpost. Also es ist ziehmlich Code das ist nur die Datei aabbox3d.h wenn jemand den Rest sehen will [url]http://irrlicht.sourceforge.net/downloads.html[/url].
Code: |
// Copyright (C) 2002-2003 Nikolaus Gebhardt // This file is part of the "Irrlicht Engine". // For conditions of distribution and use, see copyright notice in Irrlicht.h
#ifndef __IRR_AABBOX_3D_H_INCLUDED__ #define __IRR_AABBOX_3D_H_INCLUDED__
#include "irrMath.h" #include "plane3d.h" #include "line3d.h"
namespace irr { namespace core {
//! Axis aligned bounding box in 3d dimensional space. /** Has some useful methods used with occlusion culling or clipping. */ template <class T> class aabbox3d { public:
// Constructors
aabbox3d(): MinEdge(-1,-1,-1), MaxEdge(1,1,1) {}; aabbox3d(const vector3d<T>& min, const vector3d<T>& max): MinEdge(min), MaxEdge(max) {}; aabbox3d(const vector3d<T>& init): MinEdge(init), MaxEdge(init) {}; aabbox3d(T minx, T miny, T minz, T maxx, T maxy, T maxz): MinEdge(minx, miny, minz), MaxEdge(maxx, maxy, maxz) {};
// operators
inline bool operator==(const aabbox3d<T>& other) const { return (MinEdge == other.MinEdge && other.MaxEdge == MaxEdge);}; inline bool operator!=(const aabbox3d<T>& other) const { return !(MinEdge == other.MinEdge && other.MaxEdge == MaxEdge);};
// functions
//! Adds a point to the bounding box, causing it to grow bigger, //! if point is outside of the box //! \param p: Point to add into the box. void addInternalPoint(const vector3d<T>& p) { addInternalPoint(p.X, p.Y, p.Z); }
//! Adds an other bounding box to the bounding box, causing it to grow bigger, //! if the box is outside of the box //! \param b: Other bounding box to add into this box. void addInternalBox(const aabbox3d<T>& b) { addInternalPoint(b.MaxEdge); addInternalPoint(b.MinEdge); }
//! Resets the bounding box. void reset(T x, T y, T z) { MaxEdge.set(x,y,z); MinEdge = MaxEdge; }
//! Resets the bounding box. void reset(const vector3d<T>& initValue) { MaxEdge = initValue; MinEdge = initValue; }
//! Adds a point to the bounding box, causing it to grow bigger, //! if point is outside of the box. //! \param x: X Coordinate of the point to add to this box. //! \param y: Y Coordinate of the point to add to this box. //! \param z: Z Coordinate of the point to add to this box. void addInternalPoint(T x, T y, T z) { if (x>MaxEdge.X) MaxEdge.X = x; if (y>MaxEdge.Y) MaxEdge.Y = y; if (z>MaxEdge.Z) MaxEdge.Z = z;
if (x<MinEdge.X) MinEdge.X = x; if (y<MinEdge.Y) MinEdge.Y = y; if (z<MinEdge.Z) MinEdge.Z = z; }
//! Determinates if a point is within this box. //! \param p: Point to check. //! \return Returns true if the point is withing the box, and false if it is not. bool isPointInside(const vector3d<T>& p) const { return ( p.X >= MinEdge.X && p.X <= MaxEdge.X && p.Y >= MinEdge.Y && p.Y <= MaxEdge.Y && p.Z >= MinEdge.Z && p.Z <= MaxEdge.Z); };
//! Determinates if a point is within this box and its borders. //! \param p: Point to check. //! \return Returns true if the point is withing the box, and false if it is not. bool isPointTotalInside(const vector3d<T>& p) const { return ( p.X > MinEdge.X && p.X < MaxEdge.X && p.Y > MinEdge.Y && p.Y < MaxEdge.Y && p.Z > MinEdge.Z && p.Z < MaxEdge.Z); };
//! Determinates if the box intersects with an other box. //! \param other: Other box to check a intersection with. //! \return Returns true if there is a intersection with the other box, //! otherwise false. bool intersectsWithBox(const aabbox3d<T>& other) const { return (MinEdge <= other.MaxEdge && MaxEdge >= other.MinEdge); }
//! Tests if the box intersects with a line //! \param line: Line to test intersection with. //! \return Returns true if there is an intersection and false if not. bool intersectsWithLine(const line3d<T>& line) const { return intersectsWithLine(line.getMiddle(), line.getVector().normalize(), (T)(line.getLength() * 0.5)); }
//! Tests if the box intersects with a line //! \return Returns true if there is an intersection and false if not. bool intersectsWithLine(const vector3d<T>& linemiddle, const vector3d<T>& linevect, T halflength) const { const vector3d<T> e = (MaxEdge - MinEdge) * (T)0.5; const vector3d<T> t = (MinEdge + e) - linemiddle; float r;
if ((fabs(t.X) > e.X + halflength * fabs(linevect.X)) || (fabs(t.Y) > e.Y + halflength * fabs(linevect.Y)) || (fabs(t.Z) > e.Z + halflength * fabs(linevect.Z)) ) return false;
r = e.Y * (T)fabs(linevect.Z) + e.Z * (T)fabs(linevect.Y); if (fabs(t.Y*linevect.Z - t.Z*linevect.Y) > r ) return false;
r = e.X * (T)fabs(linevect.Z) + e.Z * (T)fabs(linevect.X); if (fabs(t.Z*linevect.X - t.X*linevect.Z) > r ) return false;
r = e.X * (T)fabs(linevect.Y) + e.Y * (T)fabs(linevect.X); if (fabs(t.X*linevect.Y - t.Y*linevect.X) > r) return false;
return true; }
//! 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. EIntersectionRelation3D classifyPlaneRelation(const plane3d<f32>& plane) const { vector3d<T> nearPoint(MaxEdge); vector3d<T> farPoint(MinEdge);
if (plane.Normal.X > (T)0) { nearPoint.X = MinEdge.X; farPoint.X = MaxEdge.X; }
if (plane.Normal.Y > (T)0) { nearPoint.Y = MinEdge.Y; farPoint.Y = MaxEdge.Y; }
if (plane.Normal.Z > (T)0) { nearPoint.Z = MinEdge.Z; farPoint.Z = MaxEdge.Z; }
if (plane.Normal.dotProduct(nearPoint) + plane.D > (T)0) return ISREL3D_FRONT;
if (plane.Normal.dotProduct(farPoint) + plane.D > (T)0) return ISREL3D_CLIPPED;
return ISREL3D_BACK; }
//! returns center of the bounding box vector3d<T> getCenter() const { return (MinEdge + MaxEdge) / 2; }
//! returns extend of the box vector3d<T> getExtend() const { return MaxEdge - MinEdge; }
//! stores all 8 edges of the box into a array //! \param edges: Pointer to array of 8 edges void getEdges(vector3d<T> *edges) const { core::vector3df middle = (MinEdge + MaxEdge) / 2; core::vector3df diag = middle - MaxEdge;
/* Edges are stored in this way: Hey, am I an ascii artist, or what? :) niko. /1--------/3 / | / | / | / | 5---------7 | | 0- - -| -2 | / | / |/ | / 4---------6/ */
edges[0].set(middle.X + diag.X, middle.Y + diag.Y, middle.Z + diag.Z); edges[1].set(middle.X + diag.X, middle.Y - diag.Y, middle.Z + diag.Z); edges[2].set(middle.X + diag.X, middle.Y + diag.Y, middle.Z - diag.Z); edges[3].set(middle.X + diag.X, middle.Y - diag.Y, middle.Z - diag.Z); edges[4].set(middle.X - diag.X, middle.Y + diag.Y, middle.Z + diag.Z); edges[5].set(middle.X - diag.X, middle.Y - diag.Y, middle.Z + diag.Z); edges[6].set(middle.X - diag.X, middle.Y + diag.Y, middle.Z - diag.Z); edges[7].set(middle.X - diag.X, middle.Y - diag.Y, middle.Z - diag.Z); }
//! returns if the box is empty, which means that there is //! no space within the min and the max edge. bool isEmpty() const { core::vector3df d = MinEdge - MaxEdge; if (d.X < 0) d.X = -d.X; if (d.Y < 0) d.Y = -d.Y; if (d.Z < 0) d.Z = -d.Z;
return (d.X < ROUNDING_ERROR && d.Y < ROUNDING_ERROR && d.Z < ROUNDING_ERROR); }
//! repairs the box, if for example MinEdge and MaxEdge are swapped. void repair() { T t;
if (MinEdge.X > MaxEdge.X) { t=MinEdge.X; MinEdge.X = MaxEdge.X; MaxEdge.X=t; } if (MinEdge.Y > MaxEdge.Y) { t=MinEdge.Y; MinEdge.Y = MaxEdge.Y; MaxEdge.Y=t; } if (MinEdge.Z > MaxEdge.Z) { t=MinEdge.Z; MinEdge.Z = MaxEdge.Z; MaxEdge.Z=t; } }
//! Calculates a new interpolated bounding box. //! \param other: other box to interpolate between //! \param d: value between 0.0f and 1.0f. aabbox3d<T> getInterpolated(const aabbox3d<T>& other, f32 d) const { f32 inv = 1.0f - d; return aabbox3d<T>((other.MinEdge*inv) + (MinEdge*d), (other.MaxEdge*inv) + (MaxEdge*d)); }
// member variables vector3d<T> MinEdge; vector3d<T> MaxEdge; };
} // end namespace core } // end namespace irr
#endif
|
|