col Namespace Reference

Collision detection namespace. More...


Classes

struct  BoxFiller
 Helpers for Boxtree::Boxtree. More...
struct  compElemByCenter
 Compare two elemntary boxes by the center point along one axis. More...
struct  compElemByMin
 Compare two elemntary boxes by the center point along one axis. More...
class  Boxtree
class  BoxtreePrecomp
 Contains all things that can be precomputed before a traversal of Boxtree's. More...
class  ElemBox
 Elementary box, enclosing one polygon, for Boxtree. More...
class  ConvexHull
struct  SepPlane
struct  DopFiller
struct  Dop
 A DOP is represented by NumOri (=k) many plane offsets. More...
struct  ElemDop
 Elementary DOP enclosing one polygon. More...
struct  DopTransform
 Affine transformation for DOP re-alignment. More...
struct  DopNode
 DOP node of the DOP hierarchy. More...
class  DopTree
class  XCollision
 Exceptions for Collision detection module. More...
class  XQueueTooMany
class  XQueueNoLock
class  XDopTree
 Will be raised by DopTree. More...
class  XColBug
 Will be raised by collision detection module, if a bug occurs somewhere in the code. More...
class  XBoxtree
 Will be raised by BoxTree. More...
class  Grid
struct  GridObjLtstr
class  GridCell
class  GridObj
class  VtableTest_Pnt3f
class  VtableTest_Vec3f
class  VtableTest1
class  VtableTest2
struct  Callback
 This is a functor for collision callbacks. More...
struct  PolygonIntersectionData
struct  Data
 Holds results from collision detection and client data. More...
class  CollisionPipeline
 This implements the whole collision detection pipeline, from front-end over broad-phase(s) to narrow-phase. More...
struct  SyncFun
 This is a functor for synchronization with other threads. More...
class  ColObj
 One collidable object. More...
class  ColPair
 Pairs of ColPObjs's. More...
class  MatrixCell
 A single cell of the collision interest matrix. More...
class  Matrix
 The collision interest matrix. More...
struct  ColPipelineData
 Struct to store some things which are used in Collision Detection Pipeline. More...
class  Queue
struct  Request
 Each request from the application is encapsulated by an instance of this class. More...
struct  EquivPoint
struct  TopoFace
 A face is a sorted array of indices into some vertrex array. More...
class  Topology
 Zur Beschreibung von Inzidenz- und Adjazenz-Relationen. More...
class  VertexIterator
struct  lessByAngle
 Compare points by angle. More...
struct  sBF
 contains some state across different invocations of addFace() More...
class  NanoTimer
 Timer with nanoseconds resolution. More...
class  FibRand
 Lagged Fibonacci random sequence. More...
class  VisDebug

Typedefs

typedef std::vector< const
DopNode * > 
DopNodeList
typedef bool(*) PolyIntersectT (Data *data)
 User-provided function for intersecting a pair of polygons.

Enumerations

enum  LevelOfDetectionE { LEVEL_BOX, LEVEL_HULL, LEVEL_EXACT }
 Detection levels for Callback.
enum  AlgoE { ALGO_DEFAULT, ALGO_DOPTREE, ALGO_BOXTREE }
 Algorithm to apply for rigid collision detection. More...
enum  RequestE {
  ADD_OBJECT, ADD_CALLBACK, REMOVE_CALLBACK, ACTIVATE_OBJECT,
  DEACTIVATE_OBJECT, ADD_CYCLE_CALLBACK
}
 The types of requests (besides check()) to the collision detection module. More...

Functions

 BOOST_STATIC_ASSERT (Boxtree::M_MaxNVertices==4)
bool intersectPolygons (const Pnt3f *poly1, int plSize1, const Pnt3f *poly2, int plSize2, const unsigned int *index1, const unsigned int *index2, const osg::Matrix *cxform)
 Check if two polygons intersect.
bool intersectQuadrangles (const osg::Pnt3f &polyVv0, const osg::Pnt3f &polyVv1, const osg::Pnt3f &polyVv2, const osg::Pnt3f &polyVv3, const osg::Pnt3f &polyUv0, const osg::Pnt3f &polyUv1, const osg::Pnt3f &polyUv2, const osg::Pnt3f &polyUv3, const osg::Vec3f &normal1V, const osg::Vec3f &normal2V)
 Checks whether two quadrangles intersect.
bool intersectTriangles (const Pnt3f &polyVv0, const Pnt3f &polyVv1, const Pnt3f &polyVv2, const Pnt3f &polyUv0, const Pnt3f &polyUv1, const Pnt3f &polyUv2)
 Checks if two triangles intersect.
bool intersectTriangles (const Pnt3f &polyVv0, const Pnt3f &polyVv1, const Pnt3f &polyVv2, const Pnt3f &polyUv0, const Pnt3f &polyUv1, const Pnt3f &polyUv2, const Vec3f &n1V, const Vec3f &n2V)
 Checks if two triangles intersect.
bool intersectCoplanarEdges (const Pnt3f &v0V, const Pnt3f &v1V, const Pnt3f &u0V, const Pnt3f &u1V, unsigned int x, unsigned int y)
 Checks if the edges intersect in 2D.
bool intersectEdgePolygon (const Pnt3f &v1, const Pnt3f &v2, const Pnt3f *poly, unsigned int plSize, const Vec3f &normalV, unsigned int x, unsigned int y)
 Checks, if edge intersects polygon.
bool intersectEdgePolygon (const Pnt3f &v1, const Pnt3f &v2, const Pnt3f *poly, unsigned int plSize)
 This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
bool intersectArbPolygons (const Pnt3f *poly1, unsigned int plSize1, const Pnt3f *poly2, unsigned int plSize2, const Vec3f &normal1V, const Vec3f &normal2V)
 Checks if two polygons intersect.
bool intersectArbPolygons (const Pnt3f *poly1, unsigned int plSize1, const Pnt3f *poly2, unsigned int plSize2)
 This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
bool intersectPolygons (const osg::Pnt3f *poly1, int plSize1, const osg::Pnt3f *poly2, int plSize2, const unsigned int *index1=NULL, const unsigned int *index2=NULL, const osg::Matrix *cxform=NULL)
bool intersectCoplanarTriangles (const osg::Vec3f &normalV, const osg::Pnt3f &polyVv0, const osg::Pnt3f &polyVv1, const osg::Pnt3f &polyVv2, const osg::Pnt3f &polyUv0, const osg::Pnt3f &polyUv1, const osg::Pnt3f &polyUv2)
bool intersectTriangles (const osg::Pnt3f &polyVv0, const osg::Pnt3f &polyVv1, const osg::Pnt3f &polyVv2, const osg::Pnt3f &polyUv0, const osg::Pnt3f &polyUv1, const osg::Pnt3f &polyUv2)
bool intersectTriangles (const osg::Pnt3f &polyVv0, const osg::Pnt3f &polyVv1, const osg::Pnt3f &polyVv2, const osg::Pnt3f &polyUv0, const osg::Pnt3f &polyUv1, const osg::Pnt3f &polyUv2, const osg::Vec3f &n1, const osg::Vec3f &n2)
bool intersectEdgePolygon (const osg::Pnt3f &v1, const osg::Pnt3f &v2, const osg::Pnt3f *poly, int c, const osg::Pnt3f &normalV, unsigned int x, unsigned int y)
bool intersectEdgePolygon (const osg::Pnt3f &v1, const osg::Pnt3f &v2, const osg::Pnt3f *poly, unsigned int plSize)
bool intersectArbPolygons (const osg::Pnt3f *poly1, unsigned int plSize1, const osg::Pnt3f *poly2, unsigned int plSize2)
bool intersectArbPolygons (const osg::Pnt3f *poly1, unsigned int plSize1, const osg::Pnt3f *poly2, unsigned int plSize2, const osg::Vec3f &normal1V, const osg::Vec3f &normal2V)
bool intersectCoplanarEdges (const osg::Pnt3f &v0V, const osg::Pnt3f &v1V, const osg::Pnt3f &u0V, const osg::Pnt3f &u1V, unsigned int x, unsigned int y)
 BOOST_STATIC_ASSERT (sizeof(VtableTest1)==sizeof(VtableTest2))
 BOOST_STATIC_ASSERT (sizeof(osg::Pnt3f)!=sizeof(VtableTest_Pnt3f))
 BOOST_STATIC_ASSERT (sizeof(osg::Vec3f)!=sizeof(VtableTest_Vec3f))
float operator * (const Vec4f &vec4, const Pnt3f &pnt3)
Pnt3f barycenter (const MFPnt3f *points, const unsigned int index[], const unsigned int nindices)
void getNodeBBox (NodePtr node, float min[3], float max[3])
GeometryPtr getGeom (const NodePtr node)
MFPnt3f * getPoints (const NodePtr node)
MFPnt3f * getPoints (const GeometryPtr geo)
void mergeGeom (const NodePtr &subtree, NodePtr *geonode)
void mlerp (osg::Matrix *intermat, const osg::Matrix &m1, const osg::Matrix &m2, float t)
unsigned int sign (double &x)
unsigned int sign (int x)
Creation, desctruction, assignments
Constructors and desctructors
void fillDops (const osg::NodePtr &node, const osg::GeometryPtr &geo, const osg::FaceIterator &fi, void *data)
Vector, Matrix, and Transformation Math
float operator * (const Vec3f &vec3, const Vec4f &vec4)
 Several 'vector * vector' and 'vector * point' products.
float operator * (const Pnt3f &pnt, const float vec[3])
 This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
float operator * (const osg::Vec4f &vec4, const Pnt3f &pnt3)
 This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
float operator * (const Pnt3f &pnt3, const Vec3f &vec3)
 This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
void operator+= (Vec4f &vec4, const Vec3f &vec3)
 Vec4f += Vec3f.
Pnt3f lincomb (float c1, const Pnt3f &pnt1, float c2, const Pnt3f &pnt2)
 Affine combination of two points.
void getTransfomUpto (const osg::NodePtr &cur, const osg::NodePtr &upto, osg::Matrix &result)
 Combine all transformation matrices between two nodes in the graph.
void iterFaces (const osg::NodePtr &node, void(*callback)(const osg::NodePtr &, const osg::GeometryPtr &, const osg::FaceIterator &, void *), void *data)
 Calls a function for every face in the scenegraph.
void countFaces (const osg::NodePtr &, const osg::GeometryPtr &, const osg::FaceIterator &, void *data)
 Count the number of faces in a scenegraph.
float dist2 (const Pnt3f &pnt1, const Pnt3f &pnt2)
 Square distance between 2 points.
float dist (const Pnt3f &pnt1, const Pnt3f &pnt2)
 Distance between 2 points.
Pnt3f barycenter (const Pnt3f *points, const unsigned int npoints)
 Average of an array of points.
Pnt3f barycenter (const vector< Pnt3f > &points)
 This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
Pnt3f barycenter (const Pnt3f *points, const unsigned int index[], const unsigned int nindices)
 Average of an array of indexed points.
Pnt3f barycenter (const osg::MFPnt3f *points, const unsigned int index[], const unsigned int nindices)
 This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
Pnt3f barycenter (const vector< Pnt3f > &points, const TopoFace &face)
 This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
bool collinear (const Vec3f &a, const Vec3f &b)
 Test if two vectors are collinear.
bool coplanar (const Pnt3f &p0, const Pnt3f &p1, const Pnt3f &p2, const Pnt3f &q0, const Pnt3f &q1, const Pnt3f &q2)
 Test if two triangles (planes / polygons) are coplanar.
Vec3f operator * (const osg::Matrix &m, const Vec3f &v)
 Matrix * Vec3f.
Pnt3f mulM3Pnt (const osg::Matrix &m, const Pnt3f &p)
 Matrix * Pnt3f.
Pnt3f operator * (const osg::Matrix &m, const Pnt3f &p)
 Matrix * vector.
osg::Matrix operator * (const osg::Matrix &m1, const osg::Matrix &m2)
 Matrix * matrix.
Vec3f mulMTVec (const osg::Matrix &m, const Vec3f &v)
 Transposed matrix * Vec3f.
void printMat (const osg::Matrix &m, FILE *file)
 Print a matrix.
void printPnt (const osg::Pnt3f &p, FILE *file)
 Print a point.
void dominantIndices (const Vec3f &v, unsigned int *x, unsigned int *y)
 Dominant coord plane which v is "most orthogonal" to.
void dominantIndices (const Vec3f &v, unsigned int *x, unsigned int *y, unsigned int *z)
 This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
unsigned int dominantIndex (const Vec3f &v)
 Dominant coord axis which v is "most parallel" to.
Vec3f triangleNormal (const Pnt3f &p0, const Pnt3f &p1, const Pnt3f &p2)
 Normal of a triangle defined by 3 points.
osg::Matrix axisToMat (const Vec3f &a, float d)
 Convert a rotation given by axis & angle to a matrix.
unsigned int discretizeOri (osg::Quaternion q, unsigned int r)
 Convert an orientation (quarternion) into an integer (e.g., index).
void mlerp (OSG::Matrix *intermat, const OSG::Matrix &m1, const OSG::Matrix &m2, float t)
 Matrix linear interpolation.
Geometry
void sortVerticesCounterClockwise (const vector< Pnt3f > &vertex, const Vec3f &normal, TopoFace &face)
 Sort vertices of a face such that they occur counter clockwise.
osg::NodePtr geomFromPoints (const vector< Pnt3f > &vertex, vector< TopoFace > &face, int gl_type, bool skip_redundant, const Vec3f normals[])
 Create a polyhedron from simple vertex and face arrays.
osg::NodePtr geomFromPoints (const Pnt3f vertex[], unsigned int nvertices, unsigned int face[], const unsigned int face_nv[], unsigned int nfaces, int gl_type, bool skip_redundant, const Vec3f normals[])
 This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
osg::NodePtr makeCube (float radius, int gl_type)
 Create a cube as OpenSG object.
void getNodeBBox (osg::NodePtr node, float min[3], float max[3])
 Get BoundingBox of an osg-node.
osg::GeometryPtr getGeom (const osg::NodePtr node)
 Return the pointer to the geometry core of the node.
osg::MFPnt3f * getPoints (const osg::NodePtr node)
 Return the pointer to the multi-field of the points.
osg::MFPnt3f * getPoints (const osg::GeometryPtr geo)
 This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
osg::GeoPositions3fPtr getPositions (const osg::NodePtr node)
 Return the GeoPositionsPtr of a node.
void calcVertexNormals (const osg::NodePtr node, const float creaseAngle)
 Calculate vertex normals for all geometries in a subtree.
osg::NodePtr findGeomNode (const osg::NodePtr node)
 Find the first node that has a geometry.
osg::MaterialPtr findMaterial (const osg::NodePtr node)
 Return the material a geometry node is being drawn with.
void addFace (const osg::NodePtr &node, const osg::GeometryPtr &geo, const osg::FaceIterator &face, sBF *bf)
 Add one face to a geometry/node; used by addAllFaces.
void addAllFaces (const osg::NodePtr &root, sBF *bf)
 Copy all faces in the subtree into one geometry; used by mergeGeom().
void mergeGeom (const osg::NodePtr &subtree, osg::NodePtr *geonode)
 Merge all geometries in a subtree into a node.
Timers, timing, sleeping, etc.
void sleep (unsigned int microseconds)
 Sleep n microseconds.
float time (void)
 Get the user time in milliseconds.
Random numbers
double my_drand48 (void)
 Substitute for the drand48() function under Unix (needed under Windoze).
unsigned int pseudo_random (void)
 Pseudo random number generator.
float pseudo_randomf (void)
 Pseudo random number generator.
Floating-Point Tricks
unsigned int sign (float &x)
 Returns 0 if x < 0, 0x80000000 otherwise.
Misc
bool lockToProcessor (unsigned int processor)
 Lock the calling process to a certain processor.
Intersection Tests
bool isectCoplanarTriangles (const Vec3f &normalV, const Pnt3f &polyVv0, const Pnt3f &polyVv1, const Pnt3f &polyVv2, const Pnt3f &polyUv0, const Pnt3f &polyUv1, const Pnt3f &polyUv2)
 Checks whether two coplanar triangles intersect.
bool isectCoplanarEdges (const Pnt3f &v0V, const Pnt3f &v1V, const Pnt3f &u0V, const Pnt3f &u1V, unsigned int x, unsigned int y)
 Checks if the edges intersect in 2D.
void isectEdgePolygon (const Pnt3f &v1, const Pnt3f &v2, const Pnt3f *poly, unsigned int plSize, const Vec3f &normalV, unsigned int x, unsigned int y, bool *isect, bool *oneside)
 Checks, if edge intersects polygon in 2D.
void isectEdgeTriangle (const Pnt3f &v1, const Pnt3f &v2, const Pnt3f *poly, const Vec3f &normalV, unsigned int x, unsigned int y, bool *isect, bool *oneside)
bool pointInPolygon (const Pnt3f &pt, const Pnt3f *poly, unsigned int plSize, unsigned int x, unsigned int y)
 Check if point is inside polygon.
bool pointInTriangle (const Pnt3f &pt, const Pnt3f &v0, const Pnt3f &v1, const Pnt3f &v2, unsigned int x, unsigned int y)
 Check whether point is inside triangle.

Variables

const float M_InitEta = 0.1
 Some constants for the separating planes algo ConvexHull::check(); optimal values determined by experiments.
const float M_MaxSteps = 150
const float M_AnnealingFactor = 0.97
int vvv
const unsigned int MaxNVertices = 10
 Maximal number of vertices a polygon is allowed to contain.
const float NearZero = 1E-6
 Epsilon; all collision detection math will use this threshold.


Detailed Description

Collision detection namespace.

Typedef Documentation

typedef bool(*) col::PolyIntersectT(Data *data)

User-provided function for intersecting a pair of polygons.

Parameters:
data contains various info about the pair of objects and the pair of polygons to be checked
The user can provide her own function for intersecting polygons. Whenever a collision detection algorithm has to determine the intersection status of a pair of polygons, it will call this function. Whether or not the application program really checks the intersection is up to the application programmer; it could be used for other things like coloring the polygons.

data->polisecdata->pgon[0] is guaranteed to be a member of data->geom[0], and data->polisecdata->pgon[1] is part of data->geom[1].

Author:
Gabriel Zachmann
Todo:
Als Funktor machen!


Enumeration Type Documentation

enum col::AlgoE

Algorithm to apply for rigid collision detection.

Enumerator:
ALGO_DEFAULT  this is usually the best

enum col::RequestE

The types of requests (besides check()) to the collision detection module.

Warning:
If you change this, you must change Request::Names!


Function Documentation

void col::addAllFaces ( const osg::NodePtr &  root,
sBF *  bf 
)

Copy all faces in the subtree into one geometry; used by mergeGeom().

Parameters:
root root of the subtree
bf contains state; must be init'ed by caller

void col::addFace ( const osg::NodePtr &  node,
const osg::GeometryPtr &  geo,
const osg::FaceIterator &  face,
sBF *  bf 
)

Add one face to a geometry/node; used by addAllFaces.

Parameters:
node/geo the node / geometry to which the face is added
face points to the face to be added
bf contains state across successive invocations
Implementation:
Only for internal usage, probably.

osg::Matrix col::axisToMat ( const Vec3f &  a,
float  d 
)

Convert a rotation given by axis & angle to a matrix.

Parameters:
a axis (unit vector)
d angle (radians)
Returns:
m rotation matrix
Precondition:
  • The matrix will be used via "vector * matrix".
  • The axis must be a unit vector.
The axis/angle have the meaning: "rotate about the axis with angle deg" The right-hand rule is used.

The matrix will be of the form $ \left( \begin{array}{cccc} & & & 0 \\ & \mbox{Rot} & & 0 \\ & & & 0 \\ 0 & 0 & 0 & 1 \end{array} \right) $ (Source: W. Schindler)

Implementation:
Ported from Y/conversion.c
Todo:
d = -d; kann man wahrscheinlich wieder rauswerfen, wenn man unten die Transposition auch entfernt.

Pnt3f col::barycenter ( const Pnt3f *  points,
const unsigned int  index[],
const unsigned int  nindices 
)

Average of an array of indexed points.

Parameters:
points the array
index,nindices array of indices into points
Returns:
The average over all points[ index[i] ], i = 0 .. nindices-1.
Warning:
No range check on indices will done, i.e., indices pointing outside points[] will produce garbage or an FPE!

Pnt3f col::barycenter ( const Pnt3f *  points,
const unsigned int  npoints 
)

Average of an array of points.

Parameters:
points the array
npoints number of points
Returns:
The average.

void col::calcVertexNormals ( const osg::NodePtr  node,
const float  creaseAngle = 90.0 
)

Calculate vertex normals for all geometries in a subtree.

Parameters:
node root of subtree to be processed
creaseAngle dihedral(?) angles larger than this won't be averaged (degrees)

bool col::collinear ( const Vec3f &  a,
const Vec3f &  b 
)

Test if two vectors are collinear.

Parameters:
a,b the vectors
Returns:
true if collinear, false otherwise.
Check wether or not a = l * b, l!=0. A 0 vector is not considered collinear with any other vector (if both a and b are 0, they are still considered not collinear).

This is (hopefully) only a temporary function, until available from OSG.

bool col::coplanar ( const Pnt3f &  p0,
const Pnt3f &  p1,
const Pnt3f &  p2,
const Pnt3f &  q0,
const Pnt3f &  q1,
const Pnt3f &  q2 
)

Test if two triangles (planes / polygons) are coplanar.

Parameters:
p0,p1,p2 first triangle / plane / polygon
q0,q1,q2 second ...
Returns:
true if colplanar, false otherwise.
Check wether the two planes given by the 2x3 sets of points are coplanar. If the two sets of points are from two different polygons, then this function returns true, if both polygons lie in the same plane.

Precondition:
At least one of the two triangles should yield a normal unequal 0.
Warning:
Not optimized.

void col::countFaces ( const osg::NodePtr &  ,
const osg::GeometryPtr &  ,
const osg::FaceIterator &  ,
void *  data 
)

Count the number of faces in a scenegraph.

Warning:
Don't call it directly, use iterFaces!

unsigned int col::discretizeOri ( osg::Quaternion  q,
unsigned int  r 
)

Convert an orientation (quarternion) into an integer (e.g., index).

Parameters:
q quaternion
r resolution of the discretization (must be > 0, and even)
Returns:
The integer representing the quaternion. The range is 0, .., 6*r*r*(r/2) + r*r*r = $4*r^3-1$.
Discretizes the space of all rotations (= S^3), and returns a unique integer for each rotations belonging to the same equivalence class w.r.t. this discretization.

q and -q should return the same integer.

Note that if the angle is zero (q[3]==1), you still get different indices, depending on the axis, although the rotation is always the same, namely the identity.

Note also, that bogus quaternions with a zero axis (0,0,0,a) will still produce an index within the range.

So, the range of indices produced by this function over all "sensible" unit quaternions does not cover all of [0,$4*r^3-1$].

The discretization is done by rastering the 4-dim. unit circumcube.

Exceptions:
XCollision If r==0 or |q|<eps .
XColBug If there is an internal bug; shouldn't happen.
Warning:
If r is not even, then it will be incremented. The quaternion q must have unit length - otherwise bogus will be returned.
Bug:
I think, that if two rotations yield the same index, then they represent "close" rotations - but I haven't checked yet. (Note that the reverse statement is not true.)
See also:
...
Implementation:
The quaternion is mirrored (q=-q), if q[4]<0, so as to stay on the upper hemisphere. Then, q is projected on the surrounding unit hemicube ($[-1,1]^4$). There are 7 sides. The sides of that hemicube are superimposed with a raster: the "top" side has r*r*r squares, all other sides have r*r*(r/2) squares.
Special care has been taken to make sure that quaternions, which are projected exactly on a hemicube edge (2 or more q[i] = 1), are consistently turned into an index.

Remember that the faces of a 4-dim. cube are 3-dim cubes.

float col::dist ( const Pnt3f &  pnt1,
const Pnt3f &  pnt2 
)

Distance between 2 points.

Parameters:
pnt1 point
pnt2 point
Returns:
The distance.
This is (hopefully) only a temporary function, until available from OSG.

float col::dist2 ( const Pnt3f &  pnt1,
const Pnt3f &  pnt2 
)

Square distance between 2 points.

Parameters:
pnt1 point
pnt2 point
Returns:
The squared distance.
This is (hopefully) only a temporary function, until available from OSG.

unsigned int col::dominantIndex ( const Vec3f &  v  ) 

Dominant coord axis which v is "most parallel" to.

Parameters:
v vector
Returns:
Index of maximum coordinate of v, such that $ v_x \geq \max(v_i) $.

void col::dominantIndices ( const Vec3f &  v,
unsigned int *  x,
unsigned int *  y,
unsigned int *  z 
)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Parameters:
v Vector
x 
y 
z index of smallest vector coord (out)

void col::dominantIndices ( const Vec3f &  v,
unsigned int *  x,
unsigned int *  y 
)

Dominant coord plane which v is "most orthogonal" to.

Parameters:
v vector
x,y indices of "most orthogonal" plane (out)
Compute x and y, such that $ \min(v_i) \leq v_x \; \wedge \; \min(v_i) \leq v_y $.

osg::NodePtr col::findGeomNode ( const osg::NodePtr  node  ) 

Find the first node that has a geometry.

Parameters:
node root of subtree to be searched
Returns:
The node having a geometry, or osg::NullFC.
Make a depth-first traversal of the subtree starting at node, and return the first node that has a geometry.

osg::MaterialPtr col::findMaterial ( const osg::NodePtr  node  ) 

Return the material a geometry node is being drawn with.

Parameters:
node root of subtree to be searched
Returns:
The material a geometry node is being drawn with. Can return osg::NullFC in 2 cases: node does not have a geometry core, or, findMaterial doesn't find a material on the path from the root to node.

osg::NodePtr col::geomFromPoints ( const Pnt3f  vertex[],
unsigned int  nvertices,
unsigned int  face[],
const unsigned int  face_nv[],
unsigned int  nfaces,
int  gl_type,
bool  skip_redundant,
const Vec3f  normals[] 
)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Parameters:
vertex,nvertices vertex array (in)
face,face_nv,nfaces faces array (in, could get sorted)
gl_type = GL_LINE_LOOP, GL_POLYGON, etc...
skip_redundant skip faces with <3 vertices, if true
normals normals array (can be NULL)
Face_nv[i] contains the number of vertices of face[i]. Nfaces contains the number of faces in face. There may be redundant faces, i.e., faces with face_nv[i] = 0,1,2.

Exceptions:
XColBug If a face has more than NumOri many vertices.
Precondition:
  • normals has nfaces many normals.
  • face[i] must have Dop::NumOri many columns!
Todo:
  • immer noch wird die Variable NumOri gebraucht..

osg::NodePtr col::geomFromPoints ( const vector< Pnt3f > &  vertex,
vector< TopoFace > &  face,
int  gl_type,
bool  skip_redundant,
const Vec3f  normals[] 
)

Create a polyhedron from simple vertex and face arrays.

Parameters:
vertex vertex array (in)
face faces array (in, could get sorted)
gl_type = GL_LINE_LOOP, GL_POLYGON, etc...
skip_redundant skip faces with <3 vertices, if true
normals normals array (can be NULL)
Returns:
The node.
Create a polyhedron which is the object described by the planes given by normals, nfaces, vertex, face, face_nv. Actually, normals is only used for sorting the vertices of the faces. If normals == NULL, then we assume that vertices in face[] are already sorted in counter-clockwise order. Face contains indices into vertex.

There may be redundant faces, i.e., faces with face[i].size() = 0,1,2. The geometry will have no material.

No material is assigned.

Warning:
If normals != NULL, then face will get sorted!
Exceptions:
XColBug If there are no faces with any vertices.
Precondition:
  • Planes are given by Ori*x - d = 0.
  • normals has face.size() many normals.

osg::GeometryPtr col::getGeom ( const osg::NodePtr  node  ) 

Return the pointer to the geometry core of the node.

Exceptions:
XCollision If there is no geometry, i.e., if the dcast failed

void col::getNodeBBox ( osg::NodePtr  node,
float  min[3],
float  max[3] 
)

Get BoundingBox of an osg-node.

Parameters:
node the Inpute-Node
min,max the BBox

osg::MFPnt3f* col::getPoints ( const osg::NodePtr  node  ) 

Return the pointer to the multi-field of the points.

Warning:
Don't use the MFPnt3f pointer to modify the geometry! OpenSG will not notice the changes!
Exceptions:
XCollision If any of the dynamic_cast's returns NULL.

osg::GeoPositions3fPtr col::getPositions ( const osg::NodePtr  node  ) 

Return the GeoPositionsPtr of a node.

Exceptions:
XCollision If any of the dynamic_cast's returns NULL.

void col::getTransfomUpto ( const osg::NodePtr &  cur,
const osg::NodePtr &  upto,
osg::Matrix &  result 
)

Combine all transformation matrices between two nodes in the graph.

Parameters:
cur lowest node of the graph
upto highest node in the graph
result the resulting transformation matrix

bool col::intersectArbPolygons ( const Pnt3f *  poly1,
unsigned int  plSize1,
const Pnt3f *  poly2,
unsigned int  plSize2,
const Vec3f &  normal1V,
const Vec3f &  normal2V 
)

Checks if two polygons intersect.

Parameters:
poly1 the vertices of the first polygon
poly2 the vertices of the second polygon
normal1V,normal2V normals of polygons (optional)
Returns:
true, if the polygons intersect, false, otherwise
Checks if the two polygons intersect using intersectEdgePolygon Normals are calculated if not provided as parameters.

Warning:
If you change this function, check whether the other two polygon- functions must also be changed!!
Precondition:
poly1 and poly2 contain at least 3 vertices and are not degenerated. The vertices must be in consistent order.

bool col::intersectCoplanarEdges ( const Pnt3f &  v0V,
const Pnt3f &  v1V,
const Pnt3f &  u0V,
const Pnt3f &  u1V,
unsigned int  x,
unsigned int  y 
)

Checks if the edges intersect in 2D.

Parameters:
v0V,v1V vertices of first edge
u0V,u1V vertices of second edge
x,y indices (in {0,1,2}) to dominant plane
Returns:
true if the edges intersect false otherwise
This edge to edge test is based on Franlin Antonio's gem: "Faster Line Segment Intersection" in Graphics Gems III, pp. 199-202.

Precondition:
v0, v1, u0 and u1 describe valid non-degenerated line segments. Both line segments are coplanar.
Todo:
Optimierung: Faktorisieren, um erste zwei Berechungen nicht mehrfach mit gleichen Parametern durchzufuehren!!!

bool col::intersectEdgePolygon ( const Pnt3f &  v1,
const Pnt3f &  v2,
const Pnt3f *  poly,
unsigned int  plSize,
const Vec3f &  normalV,
unsigned int  x,
unsigned int  y 
)

Checks, if edge intersects polygon.

Parameters:
v1,v2 vertices of a line segment edge
poly vertices of an arbitrary polygon
normalV normal (optional)
x,y indices (in {0,1,2}) to dominant plane (optional)
Returns:
true, if the edge intersects the polygon, false, otherwise
Checks, if the edge intersects the polygon using an algorithm originally implemented in arbcoll.c using the Y library. The algorithm has been ported to the Cosmo 3D library. See function edgePolygon in arbcoll.c

The original function did not handle the coplanar case, this implementation does.

Precondition:
v1 and v2 describe a valid line segment, poly contains at least 3 elements, the elements in poly are all in the same plane and define a valid polygon.
Todo:
Schleife ueber intersectCoplanarEdges kann optimiert werden!

bool col::intersectPolygons ( const Pnt3f *  poly1,
int  plSize1,
const Pnt3f *  poly2,
int  plSize2,
const unsigned int *  index1,
const unsigned int *  index2,
const osg::Matrix *  cxform 
)

Check if two polygons intersect.

Parameters:
poly1,poly2 vertices of the first,second polygon
plSize1,plSize2 number of vertices of first,second polygon; may be -4 to indicate a quadstrip polygon!
index1,index2 index arrays into poly1, poly2 (possibly = NULL)
cxform coordinate transformation to transform first polygon into frame of second polygon
Returns:
true, if the polygons intersect, false, otherwise
Check if the two polygons intersect by using either the triangle intersection test by Tomas Moeller or the edge against polygon test, whichever is faster. Normals are calculated always.

If the index arrays index1/2 are set, then the vertices of the polygon are poly[index[0]], .. poly[index[plSize-1]]; otherwise, the vertices are poly[0], .., poly[plSize-1].

The edges of quadrangles can be ordered in two ways, which are distinguished by the sign of plSize1/2 ( 4 corresponds to a normal quadrangle, -4 to a quadstrip).


           quadrangle        quadstrip
              1--2             1--3
              | /|             | /|
              |/ |             |/ |
              0--3             0--2
    

If possible, pass that polygon as first parameter, which has less vertices.

Exceptions:
XCollision Falls abs(plSize1/2) > MaxNVertices.
Todo:
Da ein Viereck planar ist, braucht man eigentlich die Unterscheidung zwischen Quadrangle und Quadstrip doch nicht machen, oder?
Warning:
  • The implementation assumes, that Pnt3f has no virtual function table!!
  • If plSize1/2 < 0 and plSize != -4, then it will probably dump core; this is not checked, so as to retain performance.
Precondition:
poly1 and poly2 contain >= 3 vertices and are not degenerated. Polygons must be convex and planar. The vertices must be in consistent order (clockwise or counter-clockwise).
Implementation:
If you change this function, check whether the other two polygon- functions must also be changed!
Implementation:
Because of the index option (index1/2), I have to copy vertices under certain circumstances, which might be a little performance hit. On the other hand, if I wanted to avoid that, I would have to duplicate code ...

bool col::intersectQuadrangles ( const osg::Pnt3f &  polyVv0,
const osg::Pnt3f &  polyVv1,
const osg::Pnt3f &  polyVv2,
const osg::Pnt3f &  polyVv3,
const osg::Pnt3f &  polyUv0,
const osg::Pnt3f &  polyUv1,
const osg::Pnt3f &  polyUv2,
const osg::Pnt3f &  polyUv3,
const osg::Vec3f &  normal1V,
const osg::Vec3f &  normal2V 
)

Checks whether two quadrangles intersect.

Parameters:
polyVv0,..,polyVv3 vertices of first quadrangle (called 'V')
polyUv0,..,polyUv3 vertices of second quadrangle (called 'U')
Returns:
true, if the triangles intersect, false otherwise
Precondition:
Both quadrangles are ordered as shown (no quadstrip!)
	    1--2
	    | /|
	    |/ |
	    0--3
    

bool col::intersectTriangles ( const Pnt3f &  polyVv0,
const Pnt3f &  polyVv1,
const Pnt3f &  polyVv2,
const Pnt3f &  polyUv0,
const Pnt3f &  polyUv1,
const Pnt3f &  polyUv2,
const Vec3f &  n1V,
const Vec3f &  n2V 
)

Checks if two triangles intersect.

Parameters:
polyUv0,..,polyUv2 vertices of first triangle (called 'V')
polyVv0,..,polyVv2 vertices of second triangle (called 'U')
n1V,n2V normals for triangle V and triangle U
Returns:
true, if the triangles intersect, false otherwise.
This function is very similar to the above.

The code has been kept separate because the calculation of the normal n2V can be done after a few pre-checks which filter out a lot of triangle pairs.

Warning:
If this function is changed, make sure that you also change the overloaded funtion above!!
Precondition:
The triangles are not degenerated, i.e. all vertices are different.

bool col::intersectTriangles ( const Pnt3f &  polyVv0,
const Pnt3f &  polyVv1,
const Pnt3f &  polyVv2,
const Pnt3f &  polyUv0,
const Pnt3f &  polyUv1,
const Pnt3f &  polyUv2 
)

Checks if two triangles intersect.

Parameters:
polyUv0,..,polyUv2 vertices of first triangle (called 'V')
polyVv0,..,polyVv2 vertices of second triangle (called 'U')
Global Variables:
  • globalVar1 Comment for globalVar1
Returns:
true, if the triangles intersect, false otherwise.
Warning:
Dinge, die der Aufrufer unbedingt beachten muss...
Precondition:
The triangles are not degenerated, i.e. all vertices are different.
Checks, if two triangles intersect using a fast algorithm by Tomas Moeller. See article "A Fast Triangle-Triangle Intersection Test", Journal of Graphics Tools, 2 (2), 1997.

A preprocessing routine, that gets the vertices out of their surrounding structures suchs as csGeoSet might be considered useful, as this algorithm calculates the intersection using the Pnt3f data structure.

bool col::isectCoplanarEdges ( const Pnt3f &  v0V,
const Pnt3f &  v1V,
const Pnt3f &  u0V,
const Pnt3f &  u1V,
unsigned int  x,
unsigned int  y 
)

Checks if the edges intersect in 2D.

Parameters:
v0V,v1V vertices of first edge
u0V,u1V vertices of second edge
x,y indices (in {0,1,2}) to dominant plane
Returns:
true, if the edges intersect, false otherwise.
This edge to edge test is based on Franlin Antonio's gem: "Faster Line Segment Intersection" in Graphics Gems III, pp. 199-202.

Precondition:
v0, v1, u0 and u1 describe valid non-degenerated line segments. Both line segments are coplanar.

bool col::isectCoplanarTriangles ( const Vec3f &  normalV,
const Pnt3f &  polyVv0,
const Pnt3f &  polyVv1,
const Pnt3f &  polyVv2,
const Pnt3f &  polyUv0,
const Pnt3f &  polyUv1,
const Pnt3f &  polyUv2 
)

Checks whether two coplanar triangles intersect.

Parameters:
normalV normal vector of plane, in which both triangles must lie
polyVv0,..,polyVv2 vertices of first triangle (called 'V')
polyUv0,..,polyUv2 vertices of second triangle (called 'U')
Returns:
true, if the triangles intersect, false otherwise
Precondition:
The triangles are coplanar and normalV is plane's normal vector. Both triangles are not degenerated, i.e. all their vertices differ.
Checks, if the two coplanar triangles intersect. Algorithm by Tomas Moeller, see comment of intersectTriangle for details.

void col::isectEdgePolygon ( const Pnt3f &  v1,
const Pnt3f &  v2,
const Pnt3f *  poly,
unsigned int  plSize,
const Vec3f &  normalV,
unsigned int  x,
unsigned int  y,
bool *  isect,
bool *  oneside 
)

Checks, if edge intersects polygon in 2D.

Parameters:
v1,v2 vertices of a line segment edge
poly vertices of an arbitrary polygon
plSize size of poly
normalV normal
x,y indices (in {0,1,2}) to dominant plane
isect set if edge intersects the polygon (out)
oneside set of edge is completely on one side of the plane (out)
Checks, if the edge (v1,v2) intersects the polygon. There are three output cases:
  1. isect=true is obvious;
  2. isect=false and oneside=false means that the edge intersects the plane of the polygon but not the polygon itself;
  3. isect=false and oneside=true means that the edge is completely on one side of the plane of the polygon.

If both edge and polygon are parallel (or coplanar), then case 2 cannot happen.

Precondition:
v1 and v2 describe a valid line segment, poly contains at least 3 elements, the elements in poly are all in the same plane and define a valid polygon.
Todo:
Schleife ueber intersectCoplanarEdges koennte optimiert werden.
Implementation:
Function edgePolygon in arbcoll.c. The original function did not handle the coplanar case, this implementation does.

void col::iterFaces ( const osg::NodePtr &  node,
void(*)(const osg::NodePtr &, const osg::GeometryPtr &, const osg::FaceIterator &, void *)  callback,
void *  data 
)

Calls a function for every face in the scenegraph.

Parameters:
node root of the graph
callback the function to call
data whatever you like

Pnt3f col::lincomb ( float  c1,
const Pnt3f &  pnt1,
float  c2,
const Pnt3f &  pnt2 
)

Affine combination of two points.

Parameters:
pnt1,pnt2 points
Returns:
pnt1*c1 + pnt2*c2.
Precondition:
c1 + c2 = 1!

bool col::lockToProcessor ( unsigned int  processor  ) 

Lock the calling process to a certain processor.

Parameters:
processor the processor number
A warning is printed if the processor is not isolated (or not enabled).

Returns:
False if locking failed, true otherwise. Locking can fail if we run on a single-processor machine, or processor is out of bounds.
Precondition:
Processor >= 0.
Todo:
Implement for Windows.

osg::NodePtr col::makeCube ( float  radius,
int  gl_type 
)

Create a cube as OpenSG object.

Parameters:
radius each side of the box will be 2*size long
gl_type = GL_LINE_LOOP, GL_POLYGON, etc...
Returns:
A NodePtr to the new cube.
Creates a box with no material.

Exceptions:
XCollision See geomFromPoints().

void col::mergeGeom ( const osg::NodePtr &  subtree,
osg::NodePtr *  geonode 
)

Merge all geometries in a subtree into a node.

Parameters:
subtree root of subtree to be searched
geonode gets all the geometry (in/out)
Make a depth-first traversal of the subtree, and merge all geometry cores into a new geometry core, which will then be assigned as the new core for geonode.

Transformations will be applied to the coordinates of the vertices, so that the new geometry looks exactly like the original subtree, but does not have any transformations.

Shared geometry in the subtree will be added multiply (possibly with different rtansformations) to geonode.

Warning:
Node must not be a node in the subtree!

void col::mlerp ( OSG::Matrix *  intermat,
const OSG::Matrix &  m1,
const OSG::Matrix &  m2,
float  t 
)

Matrix linear interpolation.

Parameters:
intermat result interpolation
m1 matrix start
m2 matrix end
t 0 <= t <= 1
Calculate an in-between matrix by some sort of linear interpolation between m1 and m2. m1 and m2 should contain only scaling+rotation+translation matrices so intermat can be calc'ed correctly. Interpolates rotation, translation, *and* scalings (seperately).

I should try to interpolate those rows, which are "closest". (It's faster to use quaternions if you have to interpolate many steps.)

Pnt3f col::mulM3Pnt ( const osg::Matrix &  m,
const Pnt3f &  p 
)

Matrix * Pnt3f.

Parameters:
m matrix
p point
Returns:
A point := m(3x3) * p .
Only the upper left 3x3 part (rotation) of m is considered. This is equivalent to making the translation of m = 0.

This is (hopefully) only a temporary function, until available from OSG.

Vec3f col::mulMTVec ( const osg::Matrix &  m,
const Vec3f &  v 
)

Transposed matrix * Vec3f.

Parameters:
m matrix
v vector
Returns:
A vector := m^T * v .
Of course, only the upper left 3x3 part (rotation) of m is considered.

This is (hopefully) only a temporary function, until available from OSG.

double col::my_drand48 ( void   ) 

Substitute for the drand48() function under Unix (needed under Windoze).

Returns:
Pseudo-random number in the range [0.0 .. 1.0)
The random number is generated from rand().

Vec3f col::operator * ( const osg::Matrix &  m,
const Vec3f &  v 
)

Matrix * Vec3f.

Parameters:
m matrix
v vector
Returns:
A vector := m * v .
This is (hopefully) only a temporary function, until available from OSG.

float col::operator * ( const Pnt3f &  pnt,
const float  vec[3] 
)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Parameters:
pnt point
vec vector (float array, not OSG vector)
Returns:
The dot product (i.e., projection of pnt on the line vec through origin).

float col::operator * ( const Vec3f &  vec3,
const Vec4f &  vec4 
)

Several 'vector * vector' and 'vector * point' products.

Returns:
The dot product.
These operators are (hopefully) only temporary functions, until available from OpenSG.

The 4-th component of vec4 is ignored!

void col::operator+= ( Vec4f &  vec4,
const Vec3f &  vec3 
)

Vec4f += Vec3f.

Parameters:
vec4 4D vector
vec3 3D vector

bool col::pointInPolygon ( const Pnt3f &  pt,
const Pnt3f *  poly,
unsigned int  plSize,
unsigned int  x,
unsigned int  y 
)

Check if point is inside polygon.

Parameters:
pt the point to be tested (must be in plane of polygon)
x,y indices (in {0,1,2}) to dominant plane
poly polygon vertices
plSize size of poly
Returns:
true, if point is inside polygon, false otherwise.
Check if point pt is inside the closed polygon given by poly. pt and the vertices are 3D points, but the whole check is done with pt and poly projected onto the plane x/y, where x and y in {0,1,2}.

Precondition:
The vertices are assumed to define a closed polygon. pt is assumed to be in the supporting plane of the polygon.
Implementation:
This is the original pointInPolygon from Y (arbcoll.c).
Todo:
Fuer Dreiecke und Vierecke optimieren!

bool col::pointInTriangle ( const Pnt3f &  pt,
const Pnt3f &  v0,
const Pnt3f &  v1,
const Pnt3f &  v2,
unsigned int  x,
unsigned int  y 
)

Check whether point is inside triangle.

Parameters:
pt point
v0,v1,v2 vertices of triangle
x,y indices (in {0,1,2}) to dominant plane

void col::printMat ( const osg::Matrix &  m,
FILE *  file = stdout 
)

Print a matrix.

Parameters:
m matrix
file file
Print the matrix in row-major order. This is (hopefully) only a temporary function, until available from OSG.

void col::printPnt ( const osg::Pnt3f &  p,
FILE *  file = stdout 
)

Print a point.

Parameters:
p the point
file output file

unsigned int col::pseudo_random ( void   ) 

Pseudo random number generator.

Returns:
A number in the range [0,2147483646].
Creates the same sequence of pseudo random numbers on every platform. Use this instead of any random(), drand48(), etc., in regression test programs.

Todo:
Bug:
Not multithread-safe.
See also:
pseudo_randomf
Implementation:
Based on a linear congruential relation x(new) = a * x(old) + b (mod c). If you change c, you must change pseudo_randomf! Source: http://home.t-online.de/home/mok-kong.shen/ .

float col::pseudo_randomf ( void   ) 

Pseudo random number generator.

Returns:
A number in the range [0,1).
Creates the same sequence of pseudo random numbers on every platform. Use this instead of any random(), drand48(), etc., in regression test programs.

See also:
pseudo_random

unsigned int col::sign ( float &  x  ) 

Returns 0 if x < 0, 0x80000000 otherwise.

The test 'if ( sign(x) )' seems to be a little bit faster than 'if ( x < 0.0f )'.

For doubles and int's, use floating-point comparison instead of this function, because that's faster (see ifcomp.c).

void col::sleep ( unsigned int  microseconds  ) 

Sleep n microseconds.

Parameters:
microseconds the sleep time
Sleeps a number of microseconds.

Under Windoze, this will sleep floor( microseconds / 1000 ) milliseconds. If this amounts to 0 milliseconds, the thread will just relinquish its time slice.

Todo:
  • Funktion suchen, die Mikrosekunden kann.
Bug:
On most platforms (Windows, Linux, single-CPU SGI), this function will sleep at least 10 millliseconds! (On Linux, usleep and nanosleep don't work as advertised, as of RedHat 7.2)

void col::sortVerticesCounterClockwise ( const vector< Pnt3f > &  vertex,
const Vec3f &  normal,
TopoFace &  face 
)

Sort vertices of a face such that they occur counter clockwise.

Parameters:
vertex vertex array (in)
normal normal of face (in)
face vertex indices of the points of face (in/out)
Sort all points in face so that they will be in counterclockwise order when looked at from "outside"; "outside" is where the normal points at.

Warning:
All face[i] should be valid indices into vertex!
Precondition:
All points of face should lie in one plane in 3D.
Todo:
Use "Lamda Library" (Boost).
Implementation:
The number of cosine evaluations is N*log(N); it could be reduced to N.

float col::time ( void   ) 

Get the user time in milliseconds.

Returns:
Time in milliseconds.
The time is the user time of the process (and all children) since the process started.

Implementation:
Uses times under Unix, and GetProcessTimes under Windoze. Warning: Under Windoze, clock() returns wall-clock time, *not* user time! (contrary to what the MSDN documentation says!)

Vec3f col::triangleNormal ( const Pnt3f &  p0,
const Pnt3f &  p1,
const Pnt3f &  p2 
)

Normal of a triangle defined by 3 points.

Parameters:
p0,p1,p2 the triangle
Returns:
The normal (p1-p0) x (p2-p0).


Variable Documentation

const unsigned int col::MaxNVertices = 10

Maximal number of vertices a polygon is allowed to contain.

On polygons having up to MaxNVertices the intersectPolygon routines are able to perform a coordinate transformation. This maximum was introduced for performance reasons.


Generated on Tue Oct 16 18:12:44 2007 for CollDet by  doxygen 1.5.2